@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.
- package/LICENSE +25 -25
- package/README.md +20 -12
- package/dist/analysis/scope.js +5 -3
- package/dist/analysis/typeAnalyzer.js +21 -25
- package/dist/cli/index.js +14 -4
- package/dist/cli/utils.js +61 -0
- package/dist/core/codegen/class-handlers.js +6 -6
- package/dist/core/codegen/control-flow-handlers.js +10 -9
- package/dist/core/codegen/declaration-handlers.js +10 -3
- package/dist/core/codegen/destructuring-handlers.js +9 -4
- package/dist/core/codegen/expression-handlers.js +40 -29
- package/dist/core/codegen/function-handlers.js +78 -12
- package/dist/core/codegen/helpers.js +91 -14
- package/dist/core/codegen/index.js +4 -2
- package/dist/core/codegen/statement-handlers.js +9 -7
- package/package.json +2 -2
- package/scripts/precompile-headers.ts +249 -50
- package/scripts/setup-compiler.ts +63 -63
- package/src/prelude/any_value.cpp +636 -0
- package/src/prelude/any_value.hpp +369 -362
- 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} +10 -16
- package/src/prelude/library/array.cpp +191 -0
- package/src/prelude/library/array.hpp +13 -186
- package/src/prelude/library/console.cpp +125 -0
- package/src/prelude/library/console.hpp +24 -112
- package/src/prelude/library/error.cpp +100 -0
- package/src/prelude/library/error.hpp +13 -113
- package/src/prelude/library/function.cpp +69 -0
- package/src/prelude/library/function.hpp +11 -10
- package/src/prelude/library/global.cpp +96 -0
- package/src/prelude/library/global.hpp +12 -28
- package/src/prelude/library/global_usings.hpp +15 -0
- package/src/prelude/library/math.cpp +258 -0
- package/src/prelude/library/math.hpp +26 -308
- package/src/prelude/library/object.cpp +379 -0
- package/src/prelude/library/object.hpp +14 -276
- 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 +11 -39
- package/src/prelude/library/promise.cpp +131 -0
- package/src/prelude/library/promise.hpp +12 -123
- package/src/prelude/library/symbol.cpp +56 -0
- package/src/prelude/library/symbol.hpp +11 -52
- package/src/prelude/library/timer.cpp +88 -0
- package/src/prelude/library/timer.hpp +16 -92
- package/src/prelude/runtime.cpp +19 -0
- package/src/prelude/types.hpp +184 -179
- package/src/prelude/utils/access.hpp +502 -411
- package/src/prelude/utils/assignment_operators.hpp +99 -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/object.hpp +60 -3
- package/src/prelude/utils/operators.hpp +351 -336
- package/src/prelude/utils/operators_primitive.hpp +336 -336
- 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 -1
- package/src/prelude/values/async_iterator.cpp +251 -0
- package/src/prelude/values/async_iterator.hpp +111 -83
- package/src/prelude/values/function.cpp +262 -0
- package/src/prelude/values/function.hpp +62 -82
- package/src/prelude/values/iterator.cpp +309 -0
- package/src/prelude/values/iterator.hpp +33 -64
- package/src/prelude/values/number.cpp +176 -0
- package/src/prelude/values/object.cpp +159 -0
- package/src/prelude/values/object.hpp +4 -0
- package/src/prelude/values/promise.cpp +479 -0
- package/src/prelude/values/promise.hpp +79 -72
- package/src/prelude/values/prototypes/array.hpp +46 -1336
- package/src/prelude/values/prototypes/async_iterator.hpp +19 -61
- package/src/prelude/values/prototypes/function.hpp +7 -46
- package/src/prelude/values/prototypes/iterator.hpp +25 -201
- package/src/prelude/values/prototypes/number.hpp +23 -210
- package/src/prelude/values/prototypes/object.hpp +7 -23
- package/src/prelude/values/prototypes/promise.hpp +18 -196
- package/src/prelude/values/prototypes/string.hpp +39 -542
- 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/string.hpp +25 -26
- package/src/prelude/values/symbol.cpp +89 -0
- package/src/prelude/values/symbol.hpp +101 -101
- 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/values/helpers/array.hpp +0 -209
- 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 -61
- package/src/prelude/values/helpers/symbol.hpp +0 -21
|
@@ -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"
|
|
@@ -34,15 +33,6 @@
|
|
|
34
33
|
#include "values/prototypes/string.hpp"
|
|
35
34
|
#include "values/prototypes/number.hpp"
|
|
36
35
|
|
|
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"
|
|
45
|
-
|
|
46
36
|
// utilities
|
|
47
37
|
#include "utils/operators_primitive.hpp"
|
|
48
38
|
#include "utils/operators.hpp"
|
|
@@ -61,3 +51,7 @@
|
|
|
61
51
|
#include "library/object.hpp"
|
|
62
52
|
#include "library/array.hpp"
|
|
63
53
|
#include "library/global.hpp"
|
|
54
|
+
|
|
55
|
+
#include "iterator_instantiations.hpp"
|
|
56
|
+
|
|
57
|
+
#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
|
+
}
|
|
@@ -1,186 +1,13 @@
|
|
|
1
|
-
#pragma once
|
|
2
|
-
|
|
3
|
-
#include "types.hpp"
|
|
4
|
-
#include "any_value.hpp"
|
|
5
|
-
#include "utils/operators.hpp"
|
|
6
|
-
#include "utils/access.hpp"
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
}
|
|
15
|
-
auto arr = jspp::AnyValue::make_array(std::vector<jspp::AnyValue>());
|
|
16
|
-
auto arr_ptr = arr.as_array();
|
|
17
|
-
arr_ptr->length = static_cast<uint64_t>(len);
|
|
18
|
-
arr_ptr->dense.resize(static_cast<size_t>(len), jspp::Constants::UNINITIALIZED);
|
|
19
|
-
return arr;
|
|
20
|
-
}
|
|
21
|
-
std::vector<jspp::AnyValue> elements;
|
|
22
|
-
for(const auto& arg : args) {
|
|
23
|
-
elements.push_back(arg);
|
|
24
|
-
}
|
|
25
|
-
return jspp::AnyValue::make_array(std::move(elements)); }, "Array");
|
|
26
|
-
|
|
27
|
-
struct ArrayInit
|
|
28
|
-
{
|
|
29
|
-
ArrayInit()
|
|
30
|
-
{
|
|
31
|
-
// Array.isArray(value)
|
|
32
|
-
Array.define_data_property("isArray", jspp::AnyValue::make_function([](jspp::AnyValue, std::span<const jspp::AnyValue> args) -> jspp::AnyValue
|
|
33
|
-
{
|
|
34
|
-
if (args.empty()) return jspp::Constants::FALSE;
|
|
35
|
-
return jspp::AnyValue::make_boolean(args[0].is_array()); }, "isArray"));
|
|
36
|
-
|
|
37
|
-
// Array.of(...elements)
|
|
38
|
-
Array.define_data_property("of", jspp::AnyValue::make_function([](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)); }, "of"));
|
|
45
|
-
|
|
46
|
-
// Array.from(arrayLike, mapFn?, thisArg?)
|
|
47
|
-
Array.define_data_property("from", jspp::AnyValue::make_function([](jspp::AnyValue, std::span<const jspp::AnyValue> args) -> jspp::AnyValue
|
|
48
|
-
{
|
|
49
|
-
if (args.empty() || args[0].is_null() || args[0].is_undefined()) {
|
|
50
|
-
throw jspp::Exception::make_exception("Array.from requires an array-like object", "TypeError");
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
const auto& items = args[0];
|
|
54
|
-
const auto& mapFn = (args.size() > 1 && args[1].is_function()) ? args[1] : jspp::Constants::UNDEFINED;
|
|
55
|
-
const auto& thisArg = (args.size() > 2) ? args[2] : jspp::Constants::UNDEFINED;
|
|
56
|
-
|
|
57
|
-
std::vector<jspp::AnyValue> result;
|
|
58
|
-
|
|
59
|
-
auto iteratorSym = jspp::WellKnownSymbols::iterator;
|
|
60
|
-
if (items.has_property(iteratorSym->key)) {
|
|
61
|
-
auto iter = jspp::Access::get_object_iterator(items, "Array.from source");
|
|
62
|
-
auto nextFn = iter.get_own_property("next");
|
|
63
|
-
|
|
64
|
-
size_t k = 0;
|
|
65
|
-
while (true) {
|
|
66
|
-
auto nextRes = nextFn.call(iter, std::span<const jspp::AnyValue>{}, "next");
|
|
67
|
-
if (jspp::is_truthy(nextRes.get_own_property("done"))) break;
|
|
68
|
-
|
|
69
|
-
auto val = nextRes.get_own_property("value");
|
|
70
|
-
if (mapFn.is_function()) {
|
|
71
|
-
jspp::AnyValue kVal = jspp::AnyValue::make_number(k);
|
|
72
|
-
const jspp::AnyValue mapArgs[] = {val, kVal};
|
|
73
|
-
val = mapFn.call(thisArg, std::span<const jspp::AnyValue>(mapArgs, 2));
|
|
74
|
-
}
|
|
75
|
-
result.push_back(val);
|
|
76
|
-
k++;
|
|
77
|
-
}
|
|
78
|
-
} else {
|
|
79
|
-
// Array-like (length property)
|
|
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)); }, "from"));
|
|
95
|
-
|
|
96
|
-
// Array.fromAsync(iterableOrArrayLike, mapFn?, thisArg?)
|
|
97
|
-
Array.define_data_property("fromAsync", jspp::AnyValue::make_async_function([](jspp::AnyValue, std::vector<jspp::AnyValue> args) -> jspp::JsPromise
|
|
98
|
-
{
|
|
99
|
-
if (args.empty() || args[0].is_null() || args[0].is_undefined()) {
|
|
100
|
-
throw jspp::Exception::make_exception("Array.fromAsync requires an iterable or array-like object", "TypeError");
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
const auto& items = args[0];
|
|
104
|
-
const auto& mapFn = (args.size() > 1 && args[1].is_function()) ? args[1] : jspp::Constants::UNDEFINED;
|
|
105
|
-
const auto& thisArg = (args.size() > 2) ? args[2] : jspp::Constants::UNDEFINED;
|
|
106
|
-
|
|
107
|
-
std::vector<jspp::AnyValue> result;
|
|
108
|
-
|
|
109
|
-
bool isAsync = false;
|
|
110
|
-
jspp::AnyValue iter = jspp::Constants::UNDEFINED;
|
|
111
|
-
jspp::AnyValue nextFn = jspp::Constants::UNDEFINED;
|
|
112
|
-
|
|
113
|
-
if (items.has_property(jspp::WellKnownSymbols::asyncIterator->key)) {
|
|
114
|
-
auto method = items.get_property_with_receiver(jspp::WellKnownSymbols::asyncIterator->key, items);
|
|
115
|
-
if (method.is_function()) {
|
|
116
|
-
iter = method.call(items, {});
|
|
117
|
-
nextFn = iter.get_own_property("next");
|
|
118
|
-
isAsync = true;
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
if (!isAsync && items.has_property(jspp::WellKnownSymbols::iterator->key)) {
|
|
123
|
-
auto method = items.get_property_with_receiver(jspp::WellKnownSymbols::iterator->key, items);
|
|
124
|
-
if (method.is_function()) {
|
|
125
|
-
iter = method.call(items, {});
|
|
126
|
-
nextFn = iter.get_own_property("next");
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
if (!iter.is_undefined()) {
|
|
131
|
-
size_t k = 0;
|
|
132
|
-
while (true) {
|
|
133
|
-
auto nextRes = nextFn.call(iter, {});
|
|
134
|
-
|
|
135
|
-
if (nextRes.is_promise()) {
|
|
136
|
-
nextRes = co_await nextRes;
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
if (jspp::is_truthy(nextRes.get_own_property("done"))) break;
|
|
140
|
-
|
|
141
|
-
auto val = nextRes.get_own_property("value");
|
|
142
|
-
|
|
143
|
-
if (mapFn.is_function()) {
|
|
144
|
-
jspp::AnyValue kVal = jspp::AnyValue::make_number(k);
|
|
145
|
-
const jspp::AnyValue mapArgs[] = {val, kVal};
|
|
146
|
-
auto mapRes = mapFn.call(thisArg, std::span<const jspp::AnyValue>(mapArgs, 2));
|
|
147
|
-
if (mapRes.is_promise()) {
|
|
148
|
-
val = co_await mapRes;
|
|
149
|
-
} else {
|
|
150
|
-
val = mapRes;
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
result.push_back(val);
|
|
154
|
-
k++;
|
|
155
|
-
}
|
|
156
|
-
} else {
|
|
157
|
-
auto lenVal = items.get_property_with_receiver("length", items);
|
|
158
|
-
size_t len = static_cast<size_t>(jspp::Operators_Private::ToUint32(lenVal));
|
|
159
|
-
|
|
160
|
-
for (size_t k = 0; k < len; ++k) {
|
|
161
|
-
auto kVal = items.get_property_with_receiver(std::to_string(k), items);
|
|
162
|
-
if (kVal.is_promise()) {
|
|
163
|
-
kVal = co_await kVal;
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
if (mapFn.is_function()) {
|
|
167
|
-
jspp::AnyValue kNum = jspp::AnyValue::make_number(k);
|
|
168
|
-
const jspp::AnyValue mapArgs[] = {kVal, kNum};
|
|
169
|
-
auto mapRes = mapFn.call(thisArg, std::span<const jspp::AnyValue>(mapArgs, 2));
|
|
170
|
-
if (mapRes.is_promise()) {
|
|
171
|
-
kVal = co_await mapRes;
|
|
172
|
-
} else {
|
|
173
|
-
kVal = mapRes;
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
result.push_back(kVal);
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
co_return jspp::AnyValue::make_array(std::move(result)); }, "fromAsync"));
|
|
181
|
-
|
|
182
|
-
// Array[Symbol.species]
|
|
183
|
-
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
|
|
184
|
-
{ return thisVal; }, "get [Symbol.species]"));
|
|
185
|
-
}
|
|
186
|
-
} arrayInit;
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
#include "types.hpp"
|
|
4
|
+
#include "any_value.hpp"
|
|
5
|
+
#include "utils/operators.hpp"
|
|
6
|
+
#include "utils/access.hpp"
|
|
7
|
+
|
|
8
|
+
namespace jspp {
|
|
9
|
+
extern AnyValue Array;
|
|
10
|
+
void init_array();
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
using jspp::Array;
|