@ugo-studio/jspp 0.3.0 → 0.3.2
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/LICENSE +25 -25
- package/README.md +20 -12
- package/dist/cli/args.js +22 -0
- package/dist/cli/compiler.js +53 -0
- package/dist/cli/index.js +43 -107
- package/dist/cli/pch.js +71 -0
- package/dist/cli/runner.js +23 -0
- package/dist/cli/spinner.js +27 -11
- package/dist/cli/transpiler.js +20 -0
- package/dist/cli/utils.js +59 -0
- package/dist/cli/wasm.js +70 -0
- package/dist/index.js +17 -6
- package/dist/{analysis → interpreter/analysis}/scope.js +38 -3
- package/dist/{analysis → interpreter/analysis}/typeAnalyzer.js +563 -28
- package/dist/{core → interpreter/core}/codegen/class-handlers.js +1 -1
- package/dist/{core → interpreter/core}/codegen/control-flow-handlers.js +12 -11
- package/dist/{core → interpreter/core}/codegen/declaration-handlers.js +28 -9
- package/dist/{core → interpreter/core}/codegen/destructuring-handlers.js +9 -4
- package/dist/{core → interpreter/core}/codegen/expression-handlers.js +82 -88
- package/dist/{core → interpreter/core}/codegen/function-handlers.js +159 -46
- package/dist/{core → interpreter/core}/codegen/helpers.js +170 -25
- package/dist/interpreter/core/codegen/index.js +156 -0
- package/dist/{core → interpreter/core}/codegen/literal-handlers.js +9 -0
- package/dist/{core → interpreter/core}/codegen/statement-handlers.js +47 -7
- package/package.json +6 -4
- package/scripts/precompile-headers.ts +293 -50
- package/scripts/setup-compiler.ts +63 -63
- package/scripts/setup-emsdk.ts +114 -0
- package/src/prelude/any_value.cpp +888 -0
- package/src/prelude/any_value.hpp +29 -24
- package/src/prelude/{exception_helpers.hpp → exception.cpp} +53 -53
- package/src/prelude/exception.hpp +27 -27
- package/src/prelude/iterator_instantiations.hpp +10 -0
- package/src/prelude/{index.hpp → jspp.hpp} +13 -17
- package/src/prelude/library/array.cpp +191 -0
- package/src/prelude/library/array.hpp +5 -178
- package/src/prelude/library/boolean.cpp +30 -0
- package/src/prelude/library/boolean.hpp +14 -0
- package/src/prelude/library/console.cpp +125 -0
- package/src/prelude/library/console.hpp +9 -97
- package/src/prelude/library/error.cpp +100 -0
- package/src/prelude/library/error.hpp +8 -108
- package/src/prelude/library/function.cpp +69 -0
- package/src/prelude/library/function.hpp +6 -5
- package/src/prelude/library/global.cpp +98 -0
- package/src/prelude/library/global.hpp +12 -28
- package/src/prelude/library/global_usings.hpp +15 -0
- package/src/prelude/library/math.cpp +261 -0
- package/src/prelude/library/math.hpp +8 -288
- package/src/prelude/library/object.cpp +379 -0
- package/src/prelude/library/object.hpp +5 -267
- package/src/prelude/library/performance.cpp +21 -0
- package/src/prelude/library/performance.hpp +5 -20
- package/src/prelude/library/process.cpp +38 -0
- package/src/prelude/library/process.hpp +3 -31
- package/src/prelude/library/promise.cpp +131 -0
- package/src/prelude/library/promise.hpp +5 -116
- package/src/prelude/library/symbol.cpp +56 -0
- package/src/prelude/library/symbol.hpp +5 -46
- package/src/prelude/library/timer.cpp +88 -0
- package/src/prelude/library/timer.hpp +11 -87
- package/src/prelude/runtime.cpp +19 -0
- package/src/prelude/types.hpp +26 -20
- package/src/prelude/utils/access.hpp +123 -32
- package/src/prelude/utils/assignment_operators.hpp +119 -99
- package/src/prelude/utils/log_any_value/array.hpp +61 -40
- package/src/prelude/utils/log_any_value/function.hpp +39 -39
- package/src/prelude/utils/log_any_value/log_any_value.hpp +1 -1
- package/src/prelude/utils/log_any_value/object.hpp +60 -3
- package/src/prelude/utils/log_any_value/primitives.hpp +1 -1
- package/src/prelude/utils/operators.hpp +109 -94
- package/src/prelude/utils/operators_native.hpp +349 -0
- package/src/prelude/utils/well_known_symbols.hpp +24 -24
- package/src/prelude/values/array.cpp +1399 -0
- package/src/prelude/values/array.hpp +4 -0
- package/src/prelude/values/async_iterator.cpp +251 -0
- package/src/prelude/values/async_iterator.hpp +60 -32
- package/src/prelude/values/boolean.cpp +64 -0
- package/src/prelude/values/function.cpp +262 -0
- package/src/prelude/values/function.hpp +10 -30
- package/src/prelude/values/iterator.cpp +309 -0
- package/src/prelude/values/iterator.hpp +33 -64
- package/src/prelude/values/number.cpp +221 -0
- package/src/prelude/values/object.cpp +200 -0
- package/src/prelude/values/object.hpp +4 -0
- package/src/prelude/values/promise.cpp +479 -0
- package/src/prelude/values/promise.hpp +9 -2
- package/src/prelude/values/prototypes/array.hpp +46 -1348
- package/src/prelude/values/prototypes/async_iterator.hpp +19 -61
- package/src/prelude/values/prototypes/boolean.hpp +24 -0
- package/src/prelude/values/prototypes/function.hpp +7 -46
- package/src/prelude/values/prototypes/iterator.hpp +15 -191
- package/src/prelude/values/prototypes/number.hpp +30 -210
- package/src/prelude/values/prototypes/object.hpp +7 -23
- package/src/prelude/values/prototypes/promise.hpp +8 -186
- package/src/prelude/values/prototypes/string.hpp +28 -553
- package/src/prelude/values/prototypes/symbol.hpp +9 -70
- package/src/prelude/values/shape.hpp +52 -52
- package/src/prelude/values/string.cpp +485 -0
- package/src/prelude/values/symbol.cpp +89 -0
- package/src/prelude/values/symbol.hpp +101 -101
- package/dist/cli/file-utils.js +0 -20
- package/dist/cli-utils/args.js +0 -59
- package/dist/cli-utils/colors.js +0 -9
- package/dist/cli-utils/file-utils.js +0 -20
- package/dist/cli-utils/spinner.js +0 -55
- package/dist/cli.js +0 -153
- package/dist/core/codegen/index.js +0 -86
- package/src/prelude/any_value_access.hpp +0 -170
- package/src/prelude/any_value_defines.hpp +0 -190
- package/src/prelude/any_value_helpers.hpp +0 -374
- package/src/prelude/utils/operators_primitive.hpp +0 -337
- package/src/prelude/values/helpers/array.hpp +0 -199
- package/src/prelude/values/helpers/async_iterator.hpp +0 -275
- package/src/prelude/values/helpers/function.hpp +0 -109
- package/src/prelude/values/helpers/iterator.hpp +0 -145
- package/src/prelude/values/helpers/object.hpp +0 -104
- package/src/prelude/values/helpers/promise.hpp +0 -254
- package/src/prelude/values/helpers/string.hpp +0 -37
- package/src/prelude/values/helpers/symbol.hpp +0 -21
- /package/dist/{ast → interpreter/ast}/symbols.js +0 -0
- /package/dist/{ast → interpreter/ast}/types.js +0 -0
- /package/dist/{core → interpreter/core}/codegen/visitor.js +0 -0
- /package/dist/{core → interpreter/core}/constants.js +0 -0
- /package/dist/{core → interpreter/core}/error.js +0 -0
- /package/dist/{core → interpreter/core}/parser.js +0 -0
- /package/dist/{core → interpreter/core}/traverser.js +0 -0
|
@@ -65,8 +65,7 @@ namespace jspp
|
|
|
65
65
|
|
|
66
66
|
// default ctor (Undefined)
|
|
67
67
|
AnyValue() noexcept : storage(TAG_SPECIAL | VAL_UNDEFINED) {}
|
|
68
|
-
|
|
69
|
-
explicit AnyValue(double d) noexcept
|
|
68
|
+
AnyValue(double d) noexcept
|
|
70
69
|
{
|
|
71
70
|
std::memcpy(&storage, &d, 8);
|
|
72
71
|
if (storage >= TAG_BASE) [[unlikely]]
|
|
@@ -74,20 +73,28 @@ namespace jspp
|
|
|
74
73
|
storage = 0x7FF8000000000000ULL;
|
|
75
74
|
}
|
|
76
75
|
}
|
|
77
|
-
|
|
76
|
+
AnyValue(int i) noexcept
|
|
77
|
+
{
|
|
78
|
+
double d = static_cast<double>(i);
|
|
79
|
+
std::memcpy(&storage, &d, 8);
|
|
80
|
+
}
|
|
78
81
|
explicit AnyValue(bool b) noexcept : storage(TAG_BOOLEAN | (b ? 1 : 0)) {}
|
|
79
|
-
|
|
80
82
|
AnyValue(const AnyValue &other) noexcept : storage(other.storage)
|
|
81
83
|
{
|
|
82
84
|
if (is_heap_object())
|
|
83
85
|
get_ptr()->ref();
|
|
84
86
|
}
|
|
85
|
-
|
|
86
87
|
AnyValue(AnyValue &&other) noexcept : storage(other.storage)
|
|
87
88
|
{
|
|
88
89
|
other.storage = TAG_SPECIAL | VAL_UNDEFINED;
|
|
89
90
|
}
|
|
91
|
+
~AnyValue()
|
|
92
|
+
{
|
|
93
|
+
if (is_heap_object())
|
|
94
|
+
get_ptr()->deref();
|
|
95
|
+
}
|
|
90
96
|
|
|
97
|
+
// Assignments
|
|
91
98
|
AnyValue &operator=(const AnyValue &other) noexcept
|
|
92
99
|
{
|
|
93
100
|
if (this != &other)
|
|
@@ -100,7 +107,6 @@ namespace jspp
|
|
|
100
107
|
}
|
|
101
108
|
return *this;
|
|
102
109
|
}
|
|
103
|
-
|
|
104
110
|
AnyValue &operator=(AnyValue &&other) noexcept
|
|
105
111
|
{
|
|
106
112
|
if (this != &other)
|
|
@@ -112,14 +118,6 @@ namespace jspp
|
|
|
112
118
|
}
|
|
113
119
|
return *this;
|
|
114
120
|
}
|
|
115
|
-
|
|
116
|
-
~AnyValue()
|
|
117
|
-
{
|
|
118
|
-
if (is_heap_object())
|
|
119
|
-
get_ptr()->deref();
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
// Assignments
|
|
123
121
|
AnyValue &operator=(double val) noexcept
|
|
124
122
|
{
|
|
125
123
|
if (is_heap_object())
|
|
@@ -185,14 +183,9 @@ namespace jspp
|
|
|
185
183
|
static AnyValue make_string(const std::string &raw_s) noexcept;
|
|
186
184
|
static AnyValue make_object(std::initializer_list<std::pair<std::string, AnyValue>> props) noexcept;
|
|
187
185
|
static AnyValue make_object(const std::map<std::string, AnyValue> &props) noexcept;
|
|
188
|
-
static AnyValue make_object_with_proto(std::initializer_list<std::pair<std::string, AnyValue>> props, AnyValue proto) noexcept;
|
|
189
|
-
static AnyValue make_object_with_proto(const std::map<std::string, AnyValue> &props, AnyValue proto) noexcept;
|
|
190
186
|
static AnyValue make_array(std::span<const AnyValue> dense) noexcept;
|
|
191
187
|
static AnyValue make_array(const std::vector<AnyValue> &dense) noexcept;
|
|
192
188
|
static AnyValue make_array(std::vector<AnyValue> &&dense) noexcept;
|
|
193
|
-
static AnyValue make_array_with_proto(std::span<const AnyValue> dense, AnyValue proto) noexcept;
|
|
194
|
-
static AnyValue make_array_with_proto(const std::vector<AnyValue> &dense, AnyValue proto) noexcept;
|
|
195
|
-
static AnyValue make_array_with_proto(std::vector<AnyValue> &&dense, AnyValue proto) noexcept;
|
|
196
189
|
static AnyValue make_function(const JsFunctionCallable &call, const std::optional<std::string> &name = std::nullopt, bool is_constructor = true) noexcept;
|
|
197
190
|
static AnyValue make_class(const JsFunctionCallable &call, const std::optional<std::string> &name = std::nullopt) noexcept;
|
|
198
191
|
static AnyValue make_generator(const JsFunctionCallable &call, const std::optional<std::string> &name = std::nullopt) noexcept;
|
|
@@ -273,13 +266,13 @@ namespace jspp
|
|
|
273
266
|
|
|
274
267
|
bool is_generator() const noexcept;
|
|
275
268
|
|
|
276
|
-
double as_double() const noexcept
|
|
269
|
+
inline double as_double() const noexcept
|
|
277
270
|
{
|
|
278
271
|
double d;
|
|
279
272
|
std::memcpy(&d, &storage, 8);
|
|
280
273
|
return d;
|
|
281
274
|
}
|
|
282
|
-
bool as_boolean() const noexcept
|
|
275
|
+
inline bool as_boolean() const noexcept
|
|
283
276
|
{
|
|
284
277
|
return static_cast<bool>(storage & 1);
|
|
285
278
|
}
|
|
@@ -287,22 +280,27 @@ namespace jspp
|
|
|
287
280
|
auto operator co_await() const;
|
|
288
281
|
|
|
289
282
|
bool has_property(const std::string &key) const;
|
|
283
|
+
bool has_property(const AnyValue &key) const;
|
|
290
284
|
bool has_property(const char *key) const { return has_property(std::string(key)); }
|
|
291
285
|
|
|
292
286
|
AnyValue get_own_property(const std::string &key) const;
|
|
287
|
+
AnyValue get_own_property_descriptor(const AnyValue &key) const;
|
|
293
288
|
AnyValue get_own_property(const char *key) const { return get_own_property(std::string(key)); }
|
|
294
289
|
AnyValue get_own_property(uint32_t idx) const;
|
|
295
290
|
AnyValue get_own_property(int idx) const { return get_own_property(static_cast<uint32_t>(idx)); }
|
|
296
291
|
AnyValue get_own_property(const AnyValue &key) const;
|
|
292
|
+
AnyValue get_own_symbol_property(const AnyValue &key) const;
|
|
297
293
|
|
|
298
294
|
AnyValue get_property_with_receiver(const std::string &key, AnyValue receiver) const;
|
|
299
295
|
AnyValue get_property_with_receiver(const char *key, AnyValue receiver) const { return get_property_with_receiver(std::string(key), receiver); }
|
|
296
|
+
AnyValue get_symbol_property_with_receiver(const AnyValue &key, AnyValue receiver) const;
|
|
300
297
|
|
|
301
298
|
AnyValue set_own_property(const std::string &key, AnyValue value) const;
|
|
302
299
|
AnyValue set_own_property(const char *key, AnyValue value) const { return set_own_property(std::string(key), value); }
|
|
303
300
|
AnyValue set_own_property(uint32_t idx, AnyValue value) const;
|
|
304
301
|
AnyValue set_own_property(int idx, AnyValue value) const { return set_own_property(static_cast<uint32_t>(idx), value); }
|
|
305
302
|
AnyValue set_own_property(const AnyValue &key, AnyValue value) const;
|
|
303
|
+
AnyValue set_own_symbol_property(const AnyValue &key, AnyValue value) const;
|
|
306
304
|
|
|
307
305
|
AnyValue call_own_property(const std::string &key, std::span<const AnyValue> args) const;
|
|
308
306
|
AnyValue call_own_property(const char *key, std::span<const AnyValue> args) const { return call_own_property(std::string(key), args); }
|
|
@@ -313,6 +311,7 @@ namespace jspp
|
|
|
313
311
|
void define_data_property(const std::string &key, AnyValue value);
|
|
314
312
|
void define_data_property(const char *key, AnyValue value) { define_data_property(std::string(key), value); }
|
|
315
313
|
void define_data_property(const AnyValue &key, AnyValue value);
|
|
314
|
+
void define_data_property(const AnyValue &key, AnyValue value, bool writable, bool enumerable, bool configurable);
|
|
316
315
|
void define_data_property(const std::string &key, AnyValue value, bool writable, bool enumerable, bool configurable);
|
|
317
316
|
void define_data_property(const char *key, AnyValue value, bool writable, bool enumerable, bool configurable) { define_data_property(std::string(key), value, writable, enumerable, configurable); }
|
|
318
317
|
|
|
@@ -327,12 +326,15 @@ namespace jspp
|
|
|
327
326
|
AnyValue call(AnyValue thisVal, std::span<const AnyValue> args, const std::optional<std::string> &expr = std::nullopt) const;
|
|
328
327
|
AnyValue optional_call(AnyValue thisVal, std::span<const AnyValue> args, const std::optional<std::string> &expr = std::nullopt) const;
|
|
329
328
|
AnyValue construct(std::span<const AnyValue> args, const std::optional<std::string> &name = std::nullopt) const;
|
|
330
|
-
|
|
329
|
+
AnyValue &set_prototype(AnyValue proto);
|
|
331
330
|
std::string to_std_string() const;
|
|
332
|
-
std::string to_property_key() const;
|
|
333
331
|
|
|
334
332
|
inline uint64_t get_storage() const noexcept { return storage; }
|
|
335
333
|
inline void *get_raw_ptr() const noexcept { return reinterpret_cast<void *>(storage & PAYLOAD_MASK); }
|
|
334
|
+
|
|
335
|
+
bool operator==(const AnyValue &other) const noexcept;
|
|
336
|
+
bool operator==(const std::string &other) const noexcept;
|
|
337
|
+
bool operator<(const AnyValue &other) const noexcept;
|
|
336
338
|
};
|
|
337
339
|
|
|
338
340
|
struct AnyValueAwaiter
|
|
@@ -347,7 +349,10 @@ namespace jspp
|
|
|
347
349
|
{
|
|
348
350
|
return AnyValueAwaiter{*this};
|
|
349
351
|
}
|
|
352
|
+
}
|
|
350
353
|
|
|
354
|
+
namespace jspp
|
|
355
|
+
{
|
|
351
356
|
namespace Constants
|
|
352
357
|
{
|
|
353
358
|
inline const AnyValue UNINITIALIZED = AnyValue::make_uninitialized();
|
|
@@ -359,4 +364,4 @@ namespace jspp
|
|
|
359
364
|
inline const AnyValue ZERO = AnyValue::make_number(0.0);
|
|
360
365
|
inline const AnyValue ONE = AnyValue::make_number(1.0);
|
|
361
366
|
}
|
|
362
|
-
}
|
|
367
|
+
}
|
|
@@ -1,53 +1,53 @@
|
|
|
1
|
-
#
|
|
2
|
-
|
|
3
|
-
#include "
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
const char *
|
|
8
|
-
{
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
{
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
}
|
|
1
|
+
#include "jspp.hpp"
|
|
2
|
+
#include "exception.hpp"
|
|
3
|
+
#include "any_value.hpp"
|
|
4
|
+
|
|
5
|
+
namespace jspp {
|
|
6
|
+
|
|
7
|
+
const char *Exception::what() const noexcept
|
|
8
|
+
{
|
|
9
|
+
static thread_local std::string last_msg;
|
|
10
|
+
last_msg = data.to_std_string();
|
|
11
|
+
return last_msg.c_str();
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
Exception Exception::make_exception(const std::string &message, const std::string &name)
|
|
15
|
+
{
|
|
16
|
+
std::vector<AnyValue> args = {AnyValue::make_string(message)};
|
|
17
|
+
AnyValue errorObj = ::Error.construct(args, name);
|
|
18
|
+
errorObj.define_data_property("name", AnyValue::make_string(name), true, false, true);
|
|
19
|
+
|
|
20
|
+
return Exception(errorObj);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
AnyValue Exception::exception_to_any_value(const std::exception &ex)
|
|
24
|
+
{
|
|
25
|
+
if (const jspp::Exception *err = dynamic_cast<const jspp::Exception *>(&ex))
|
|
26
|
+
{
|
|
27
|
+
return err->data;
|
|
28
|
+
}
|
|
29
|
+
else
|
|
30
|
+
{
|
|
31
|
+
return AnyValue::make_string(ex.what());
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// --- THROWERS
|
|
36
|
+
AnyValue Exception::throw_unresolved_reference(const std::string &var_name)
|
|
37
|
+
{
|
|
38
|
+
throw Exception::make_exception(var_name + " is not defined", "ReferenceError");
|
|
39
|
+
}
|
|
40
|
+
AnyValue Exception::throw_uninitialized_reference(const std::string &var_name)
|
|
41
|
+
{
|
|
42
|
+
throw Exception::make_exception("Cannot access '" + var_name + "' before initialization", "ReferenceError");
|
|
43
|
+
}
|
|
44
|
+
AnyValue Exception::throw_immutable_assignment()
|
|
45
|
+
{
|
|
46
|
+
throw Exception::make_exception("Assignment to constant variable.", "TypeError");
|
|
47
|
+
}
|
|
48
|
+
AnyValue Exception::throw_invalid_return_statement()
|
|
49
|
+
{
|
|
50
|
+
throw Exception::make_exception("Return statements are only valid inside functions.", "SyntaxError");
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
} // namespace jspp
|
|
@@ -1,28 +1,28 @@
|
|
|
1
|
-
#pragma once
|
|
2
|
-
|
|
3
|
-
#include <exception>
|
|
4
|
-
#include "types.hpp"
|
|
5
|
-
#include "any_value.hpp"
|
|
6
|
-
|
|
7
|
-
namespace jspp
|
|
8
|
-
{
|
|
9
|
-
struct Exception : std::exception
|
|
10
|
-
{
|
|
11
|
-
AnyValue data;
|
|
12
|
-
|
|
13
|
-
explicit Exception(const AnyValue &value)
|
|
14
|
-
: data(value) {}
|
|
15
|
-
explicit Exception(AnyValue &&value)
|
|
16
|
-
: data(std::move(value)) {}
|
|
17
|
-
|
|
18
|
-
const char *what() const noexcept override;
|
|
19
|
-
static Exception make_exception(const std::string &message, const std::string &name);
|
|
20
|
-
static AnyValue exception_to_any_value(const std::exception &ex);
|
|
21
|
-
|
|
22
|
-
// --- THROWERS
|
|
23
|
-
static AnyValue throw_unresolved_reference(const std::string &var_name);
|
|
24
|
-
static AnyValue throw_uninitialized_reference(const std::string &var_name);
|
|
25
|
-
static AnyValue throw_immutable_assignment();
|
|
26
|
-
static AnyValue throw_invalid_return_statement();
|
|
27
|
-
};
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
#include <exception>
|
|
4
|
+
#include "types.hpp"
|
|
5
|
+
#include "any_value.hpp"
|
|
6
|
+
|
|
7
|
+
namespace jspp
|
|
8
|
+
{
|
|
9
|
+
struct Exception : std::exception
|
|
10
|
+
{
|
|
11
|
+
AnyValue data;
|
|
12
|
+
|
|
13
|
+
explicit Exception(const AnyValue &value)
|
|
14
|
+
: data(value) {}
|
|
15
|
+
explicit Exception(AnyValue &&value)
|
|
16
|
+
: data(std::move(value)) {}
|
|
17
|
+
|
|
18
|
+
const char *what() const noexcept override;
|
|
19
|
+
static Exception make_exception(const std::string &message, const std::string &name);
|
|
20
|
+
static AnyValue exception_to_any_value(const std::exception &ex);
|
|
21
|
+
|
|
22
|
+
// --- THROWERS
|
|
23
|
+
static AnyValue throw_unresolved_reference(const std::string &var_name);
|
|
24
|
+
static AnyValue throw_uninitialized_reference(const std::string &var_name);
|
|
25
|
+
static AnyValue throw_immutable_assignment();
|
|
26
|
+
static AnyValue throw_invalid_return_statement();
|
|
27
|
+
};
|
|
28
28
|
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
#include "values/iterator.hpp"
|
|
3
|
+
#include "values/async_iterator.hpp"
|
|
4
|
+
|
|
5
|
+
namespace jspp {
|
|
6
|
+
// Explicit template instantiation declarations
|
|
7
|
+
// This tells the compiler that the implementation is in libjspp.a
|
|
8
|
+
extern template class JsIterator<AnyValue>;
|
|
9
|
+
extern template class JsAsyncIterator<AnyValue>;
|
|
10
|
+
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
#
|
|
1
|
+
#ifndef JSPP_PRELUDE_JSPP_HPP
|
|
2
|
+
#define JSPP_PRELUDE_JSPP_HPP
|
|
2
3
|
|
|
3
4
|
#include "types.hpp"
|
|
4
5
|
#include "utils/well_known_symbols.hpp"
|
|
@@ -7,21 +8,19 @@
|
|
|
7
8
|
#include "values/shape.hpp"
|
|
8
9
|
#include "values/symbol.hpp"
|
|
9
10
|
#include "values/non_values.hpp"
|
|
11
|
+
#include "values/string.hpp"
|
|
12
|
+
|
|
13
|
+
#include "any_value.hpp" // Must be before iterators for AnyValueAwaiter
|
|
10
14
|
#include "values/iterator.hpp"
|
|
11
15
|
#include "values/async_iterator.hpp"
|
|
12
|
-
#include "values/string.hpp"
|
|
13
16
|
|
|
14
|
-
#include "any_value.hpp"
|
|
15
17
|
#include "values/object.hpp"
|
|
16
18
|
#include "values/array.hpp"
|
|
17
19
|
#include "values/function.hpp"
|
|
18
20
|
#include "values/promise.hpp"
|
|
19
21
|
#include "values/descriptors.hpp"
|
|
20
|
-
#include "
|
|
21
|
-
#include "any_value_access.hpp"
|
|
22
|
-
#include "any_value_defines.hpp"
|
|
22
|
+
#include "exception.hpp"
|
|
23
23
|
#include "library/error.hpp"
|
|
24
|
-
#include "exception_helpers.hpp"
|
|
25
24
|
#include "scheduler.hpp"
|
|
26
25
|
|
|
27
26
|
#include "values/prototypes/symbol.hpp"
|
|
@@ -33,18 +32,10 @@
|
|
|
33
32
|
#include "values/prototypes/promise.hpp"
|
|
34
33
|
#include "values/prototypes/string.hpp"
|
|
35
34
|
#include "values/prototypes/number.hpp"
|
|
36
|
-
|
|
37
|
-
#include "values/helpers/symbol.hpp"
|
|
38
|
-
#include "values/helpers/object.hpp"
|
|
39
|
-
#include "values/helpers/array.hpp"
|
|
40
|
-
#include "values/helpers/function.hpp"
|
|
41
|
-
#include "values/helpers/iterator.hpp"
|
|
42
|
-
#include "values/helpers/async_iterator.hpp"
|
|
43
|
-
#include "values/helpers/promise.hpp"
|
|
44
|
-
#include "values/helpers/string.hpp"
|
|
35
|
+
#include "values/prototypes/boolean.hpp"
|
|
45
36
|
|
|
46
37
|
// utilities
|
|
47
|
-
#include "utils/
|
|
38
|
+
#include "utils/operators_native.hpp"
|
|
48
39
|
#include "utils/operators.hpp"
|
|
49
40
|
#include "utils/assignment_operators.hpp"
|
|
50
41
|
#include "utils/access.hpp"
|
|
@@ -60,4 +51,9 @@
|
|
|
60
51
|
#include "library/math.hpp"
|
|
61
52
|
#include "library/object.hpp"
|
|
62
53
|
#include "library/array.hpp"
|
|
54
|
+
#include "library/boolean.hpp"
|
|
63
55
|
#include "library/global.hpp"
|
|
56
|
+
|
|
57
|
+
#include "iterator_instantiations.hpp"
|
|
58
|
+
|
|
59
|
+
#endif // JSPP_PRELUDE_JSPP_HPP
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
#include "jspp.hpp"
|
|
2
|
+
#include "library/array.hpp"
|
|
3
|
+
|
|
4
|
+
namespace jspp {
|
|
5
|
+
jspp::AnyValue Array = jspp::AnyValue::make_class(
|
|
6
|
+
std::function<AnyValue(AnyValue, std::span<const AnyValue>)>([](jspp::AnyValue thisVal, std::span<const jspp::AnyValue> args) -> jspp::AnyValue
|
|
7
|
+
{
|
|
8
|
+
if (args.size() == 1 && args[0].is_number()) {
|
|
9
|
+
double len = args[0].as_double();
|
|
10
|
+
if (len < 0 || len > 4294967295.0) { // Max uint32
|
|
11
|
+
throw jspp::Exception::make_exception("Invalid array length", "RangeError");
|
|
12
|
+
}
|
|
13
|
+
auto arr = jspp::AnyValue::make_array(std::vector<jspp::AnyValue>());
|
|
14
|
+
auto arr_ptr = arr.as_array();
|
|
15
|
+
arr_ptr->length = static_cast<uint64_t>(len);
|
|
16
|
+
arr_ptr->dense.resize(static_cast<size_t>(len), jspp::Constants::UNINITIALIZED);
|
|
17
|
+
return arr;
|
|
18
|
+
}
|
|
19
|
+
std::vector<jspp::AnyValue> elements;
|
|
20
|
+
for(const auto& arg : args) {
|
|
21
|
+
elements.push_back(arg);
|
|
22
|
+
}
|
|
23
|
+
return jspp::AnyValue::make_array(std::move(elements));
|
|
24
|
+
}), "Array");
|
|
25
|
+
|
|
26
|
+
struct ArrayInit
|
|
27
|
+
{
|
|
28
|
+
ArrayInit()
|
|
29
|
+
{
|
|
30
|
+
Array.define_data_property("isArray", jspp::AnyValue::make_function(
|
|
31
|
+
std::function<AnyValue(AnyValue, std::span<const AnyValue>)>([](jspp::AnyValue, std::span<const jspp::AnyValue> args) -> jspp::AnyValue
|
|
32
|
+
{
|
|
33
|
+
if (args.empty()) return jspp::Constants::FALSE;
|
|
34
|
+
return jspp::AnyValue::make_boolean(args[0].is_array());
|
|
35
|
+
}), "isArray"));
|
|
36
|
+
|
|
37
|
+
Array.define_data_property("of", jspp::AnyValue::make_function(
|
|
38
|
+
std::function<AnyValue(AnyValue, std::span<const AnyValue>)>([](jspp::AnyValue, std::span<const jspp::AnyValue> args) -> jspp::AnyValue
|
|
39
|
+
{
|
|
40
|
+
std::vector<jspp::AnyValue> elements;
|
|
41
|
+
for(const auto& arg : args) {
|
|
42
|
+
elements.push_back(arg);
|
|
43
|
+
}
|
|
44
|
+
return jspp::AnyValue::make_array(std::move(elements));
|
|
45
|
+
}), "of"));
|
|
46
|
+
|
|
47
|
+
Array.define_data_property("from", jspp::AnyValue::make_function(
|
|
48
|
+
std::function<AnyValue(AnyValue, std::span<const AnyValue>)>([](jspp::AnyValue, std::span<const jspp::AnyValue> args) -> jspp::AnyValue
|
|
49
|
+
{
|
|
50
|
+
if (args.empty() || args[0].is_null() || args[0].is_undefined()) {
|
|
51
|
+
throw jspp::Exception::make_exception("Array.from requires an array-like object", "TypeError");
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const auto& items = args[0];
|
|
55
|
+
const auto& mapFn = (args.size() > 1 && args[1].is_function()) ? args[1] : jspp::Constants::UNDEFINED;
|
|
56
|
+
const auto& thisArg = (args.size() > 2) ? args[2] : jspp::Constants::UNDEFINED;
|
|
57
|
+
|
|
58
|
+
std::vector<jspp::AnyValue> result;
|
|
59
|
+
|
|
60
|
+
auto iteratorSym = jspp::AnyValue::from_symbol(jspp::WellKnownSymbols::iterator);
|
|
61
|
+
if (items.has_property(iteratorSym)) {
|
|
62
|
+
auto iter = jspp::Access::get_object_iterator(items, "Array.from source");
|
|
63
|
+
auto nextFn = iter.get_own_property("next");
|
|
64
|
+
|
|
65
|
+
size_t k = 0;
|
|
66
|
+
while (true) {
|
|
67
|
+
auto nextRes = nextFn.call(iter, std::span<const jspp::AnyValue>{}, "next");
|
|
68
|
+
if (jspp::is_truthy(nextRes.get_own_property("done"))) break;
|
|
69
|
+
|
|
70
|
+
auto val = nextRes.get_own_property("value");
|
|
71
|
+
if (mapFn.is_function()) {
|
|
72
|
+
jspp::AnyValue kVal = jspp::AnyValue::make_number(k);
|
|
73
|
+
const jspp::AnyValue mapArgs[] = {val, kVal};
|
|
74
|
+
val = mapFn.call(thisArg, std::span<const jspp::AnyValue>(mapArgs, 2));
|
|
75
|
+
}
|
|
76
|
+
result.push_back(val);
|
|
77
|
+
k++;
|
|
78
|
+
}
|
|
79
|
+
} else {
|
|
80
|
+
auto lenVal = items.get_property_with_receiver("length", items);
|
|
81
|
+
size_t len = static_cast<size_t>(jspp::Operators_Private::ToUint32(lenVal));
|
|
82
|
+
|
|
83
|
+
for (size_t k = 0; k < len; ++k) {
|
|
84
|
+
auto kVal = items.get_property_with_receiver(std::to_string(k), items);
|
|
85
|
+
if (mapFn.is_function()) {
|
|
86
|
+
jspp::AnyValue kNum = jspp::AnyValue::make_number(k);
|
|
87
|
+
const jspp::AnyValue mapArgs[] = {kVal, kNum};
|
|
88
|
+
kVal = mapFn.call(thisArg, std::span<const jspp::AnyValue>(mapArgs, 2));
|
|
89
|
+
}
|
|
90
|
+
result.push_back(kVal);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
return jspp::AnyValue::make_array(std::move(result));
|
|
95
|
+
}), "from"));
|
|
96
|
+
|
|
97
|
+
Array.define_data_property("fromAsync", jspp::AnyValue::make_async_function(
|
|
98
|
+
std::function<JsPromise(AnyValue, std::vector<AnyValue>)>([](jspp::AnyValue, std::vector<jspp::AnyValue> args) -> jspp::JsPromise
|
|
99
|
+
{
|
|
100
|
+
if (args.empty() || args[0].is_null() || args[0].is_undefined()) {
|
|
101
|
+
throw jspp::Exception::make_exception("Array.fromAsync requires an iterable or array-like object", "TypeError");
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
const auto& items = args[0];
|
|
105
|
+
const auto& mapFn = (args.size() > 1 && args[1].is_function()) ? args[1] : jspp::Constants::UNDEFINED;
|
|
106
|
+
const auto& thisArg = (args.size() > 2) ? args[2] : jspp::Constants::UNDEFINED;
|
|
107
|
+
|
|
108
|
+
std::vector<jspp::AnyValue> result;
|
|
109
|
+
bool isAsync = false;
|
|
110
|
+
jspp::AnyValue iter = jspp::Constants::UNDEFINED;
|
|
111
|
+
jspp::AnyValue nextFn = jspp::Constants::UNDEFINED;
|
|
112
|
+
|
|
113
|
+
auto asyncIterSym = jspp::AnyValue::from_symbol(jspp::WellKnownSymbols::asyncIterator);
|
|
114
|
+
if (items.has_property(asyncIterSym)) {
|
|
115
|
+
auto method = items.get_own_property(asyncIterSym);
|
|
116
|
+
if (method.is_function()) {
|
|
117
|
+
iter = method.call(items, {});
|
|
118
|
+
nextFn = iter.get_own_property("next");
|
|
119
|
+
isAsync = true;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
auto iterSym = jspp::AnyValue::from_symbol(jspp::WellKnownSymbols::iterator);
|
|
124
|
+
if (!isAsync && items.has_property(iterSym)) {
|
|
125
|
+
auto method = items.get_own_property(iterSym);
|
|
126
|
+
if (method.is_function()) {
|
|
127
|
+
iter = method.call(items, {});
|
|
128
|
+
nextFn = iter.get_own_property("next");
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
if (!iter.is_undefined()) {
|
|
133
|
+
size_t k = 0;
|
|
134
|
+
while (true) {
|
|
135
|
+
auto nextRes = nextFn.call(iter, {});
|
|
136
|
+
if (nextRes.is_promise()) {
|
|
137
|
+
nextRes = co_await nextRes;
|
|
138
|
+
}
|
|
139
|
+
if (jspp::is_truthy(nextRes.get_own_property("done"))) break;
|
|
140
|
+
auto val = nextRes.get_own_property("value");
|
|
141
|
+
if (mapFn.is_function()) {
|
|
142
|
+
jspp::AnyValue kVal = jspp::AnyValue::make_number(k);
|
|
143
|
+
const jspp::AnyValue mapArgs[] = {val, kVal};
|
|
144
|
+
auto mapRes = mapFn.call(thisArg, std::span<const jspp::AnyValue>(mapArgs, 2));
|
|
145
|
+
if (mapRes.is_promise()) val = co_await mapRes; else val = mapRes;
|
|
146
|
+
}
|
|
147
|
+
result.push_back(val);
|
|
148
|
+
k++;
|
|
149
|
+
}
|
|
150
|
+
} else {
|
|
151
|
+
auto lenVal = items.get_property_with_receiver("length", items);
|
|
152
|
+
size_t len = static_cast<size_t>(jspp::Operators_Private::ToUint32(lenVal));
|
|
153
|
+
for (size_t k = 0; k < len; ++k) {
|
|
154
|
+
auto kVal = items.get_property_with_receiver(std::to_string(k), items);
|
|
155
|
+
if (kVal.is_promise()) kVal = co_await kVal;
|
|
156
|
+
if (mapFn.is_function()) {
|
|
157
|
+
jspp::AnyValue kNum = jspp::AnyValue::make_number(k);
|
|
158
|
+
const jspp::AnyValue mapArgs[] = {kVal, kNum};
|
|
159
|
+
auto mapRes = mapFn.call(thisArg, std::span<const jspp::AnyValue>(mapArgs, 2));
|
|
160
|
+
if (mapRes.is_promise()) kVal = co_await mapRes; else kVal = mapRes;
|
|
161
|
+
}
|
|
162
|
+
result.push_back(kVal);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
co_return jspp::AnyValue::make_array(std::move(result));
|
|
166
|
+
}), "fromAsync"));
|
|
167
|
+
|
|
168
|
+
// Array[Symbol.species]
|
|
169
|
+
Array.define_getter(jspp::AnyValue::from_symbol(jspp::WellKnownSymbols::species), jspp::AnyValue::make_function([](jspp::AnyValue thisVal, std::span<const jspp::AnyValue> args) -> jspp::AnyValue
|
|
170
|
+
{ return thisVal; }, "get [Symbol.species]"));
|
|
171
|
+
|
|
172
|
+
auto proto = Array.get_own_property("prototype");
|
|
173
|
+
const char *methods[] = {"push", "pop", "shift", "unshift", "join", "forEach", "map", "filter", "slice", "splice", "concat", "indexOf", "lastIndexOf", "includes", "every", "some", "reduce", "reduceRight", "flat", "flatMap", "fill", "reverse", "sort", "at", "values", "keys", "entries", "toString", "toLocaleString"};
|
|
174
|
+
for (const char *m : methods)
|
|
175
|
+
{
|
|
176
|
+
auto method_fn = jspp::ArrayPrototypes::get(m);
|
|
177
|
+
if (method_fn.has_value())
|
|
178
|
+
{
|
|
179
|
+
proto.define_data_property(m, method_fn.value(), true, false, true);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
auto iteratorSym = jspp::AnyValue::from_symbol(jspp::WellKnownSymbols::iterator);
|
|
184
|
+
proto.define_data_property(iteratorSym, jspp::ArrayPrototypes::get(iteratorSym).value(), true, false, true);
|
|
185
|
+
}
|
|
186
|
+
};
|
|
187
|
+
void init_array()
|
|
188
|
+
{
|
|
189
|
+
static ArrayInit arrayInit;
|
|
190
|
+
}
|
|
191
|
+
}
|