@ugo-studio/jspp 0.3.1 → 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/dist/cli/args.js +22 -0
- package/dist/cli/compiler.js +53 -0
- package/dist/cli/index.js +43 -117
- 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 +25 -27
- package/dist/cli/wasm.js +70 -0
- package/dist/index.js +17 -6
- package/dist/{analysis → interpreter/analysis}/scope.js +34 -1
- package/dist/{analysis → interpreter/analysis}/typeAnalyzer.js +542 -3
- package/dist/{core → interpreter/core}/codegen/class-handlers.js +1 -1
- package/dist/{core → interpreter/core}/codegen/control-flow-handlers.js +2 -2
- package/dist/{core → interpreter/core}/codegen/declaration-handlers.js +21 -9
- package/dist/{core → interpreter/core}/codegen/destructuring-handlers.js +3 -3
- package/dist/{core → interpreter/core}/codegen/expression-handlers.js +44 -61
- package/dist/{core → interpreter/core}/codegen/function-handlers.js +108 -61
- package/dist/{core → interpreter/core}/codegen/helpers.js +79 -11
- 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 +39 -1
- package/package.json +6 -4
- package/scripts/precompile-headers.ts +63 -19
- package/scripts/setup-emsdk.ts +114 -0
- package/src/prelude/any_value.cpp +851 -599
- package/src/prelude/any_value.hpp +28 -30
- package/src/prelude/jspp.hpp +3 -1
- package/src/prelude/library/boolean.cpp +30 -0
- package/src/prelude/library/boolean.hpp +14 -0
- package/src/prelude/library/error.cpp +2 -2
- package/src/prelude/library/global.cpp +2 -0
- package/src/prelude/library/math.cpp +46 -43
- package/src/prelude/library/math.hpp +2 -0
- package/src/prelude/library/object.cpp +1 -1
- package/src/prelude/types.hpp +10 -9
- package/src/prelude/utils/access.hpp +2 -2
- package/src/prelude/utils/assignment_operators.hpp +40 -20
- package/src/prelude/utils/log_any_value/log_any_value.hpp +1 -1
- package/src/prelude/utils/log_any_value/primitives.hpp +1 -1
- package/src/prelude/utils/operators.hpp +87 -87
- package/src/prelude/utils/operators_native.hpp +349 -0
- package/src/prelude/utils/well_known_symbols.hpp +13 -13
- package/src/prelude/values/array.cpp +3 -3
- package/src/prelude/values/boolean.cpp +64 -0
- package/src/prelude/values/number.cpp +137 -92
- package/src/prelude/values/object.cpp +163 -122
- package/src/prelude/values/prototypes/boolean.hpp +24 -0
- package/src/prelude/values/prototypes/number.hpp +8 -1
- 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 -88
- package/src/prelude/utils/operators_primitive.hpp +0 -337
- /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
|
@@ -1,51 +1,88 @@
|
|
|
1
1
|
#include "jspp.hpp"
|
|
2
2
|
#include "values/prototypes/number.hpp"
|
|
3
3
|
|
|
4
|
-
namespace jspp
|
|
5
|
-
|
|
6
|
-
namespace NumberPrototypes {
|
|
7
|
-
|
|
8
|
-
std::string number_to_radix_string(double value, int radix)
|
|
4
|
+
namespace jspp
|
|
9
5
|
{
|
|
10
|
-
if (std::isnan(value))
|
|
11
|
-
return "NaN";
|
|
12
|
-
if (!std::isfinite(value))
|
|
13
|
-
return value > 0 ? "Infinity" : "-Infinity";
|
|
14
6
|
|
|
15
|
-
|
|
7
|
+
// --- JsNumber Implementation ---
|
|
16
8
|
|
|
17
|
-
|
|
9
|
+
namespace JsNumber
|
|
18
10
|
{
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
11
|
+
std::string to_std_string(double num)
|
|
12
|
+
{
|
|
13
|
+
if (std::isnan(num))
|
|
14
|
+
return "NaN";
|
|
15
|
+
if (std::abs(num) >= 1e21 || (std::abs(num) > 0 && std::abs(num) < 1e-6))
|
|
16
|
+
{
|
|
17
|
+
std::ostringstream oss;
|
|
18
|
+
oss << std::scientific << std::setprecision(4) << num;
|
|
19
|
+
return oss.str();
|
|
20
|
+
}
|
|
21
|
+
else
|
|
22
|
+
{
|
|
23
|
+
std::ostringstream oss;
|
|
24
|
+
oss << std::setprecision(6) << std::fixed << num;
|
|
25
|
+
std::string s = oss.str();
|
|
26
|
+
s.erase(s.find_last_not_of('0') + 1, std::string::npos);
|
|
27
|
+
if (!s.empty() && s.back() == '.')
|
|
28
|
+
s.pop_back();
|
|
29
|
+
return s;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
25
32
|
|
|
26
|
-
|
|
27
|
-
|
|
33
|
+
std::string to_std_string(const AnyValue &value)
|
|
34
|
+
{
|
|
35
|
+
return to_std_string(value.as_double());
|
|
36
|
+
}
|
|
28
37
|
|
|
29
|
-
|
|
30
|
-
res = "0";
|
|
31
|
-
else
|
|
32
|
-
{
|
|
33
|
-
while (intPart > 0)
|
|
38
|
+
std::string to_radix_string(double value, int radix)
|
|
34
39
|
{
|
|
35
|
-
|
|
36
|
-
|
|
40
|
+
if (std::isnan(value))
|
|
41
|
+
return "NaN";
|
|
42
|
+
if (!std::isfinite(value))
|
|
43
|
+
return value > 0 ? "Infinity" : "-Infinity";
|
|
44
|
+
|
|
45
|
+
long long intPart = static_cast<long long>(value);
|
|
46
|
+
|
|
47
|
+
if (radix == 10)
|
|
48
|
+
{
|
|
49
|
+
return AnyValue::make_number(value).to_std_string();
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
bool negative = intPart < 0;
|
|
53
|
+
if (negative)
|
|
54
|
+
intPart = -intPart;
|
|
55
|
+
|
|
56
|
+
std::string chars = "0123456789abcdefghijklmnopqrstuvwxyz";
|
|
57
|
+
std::string res = "";
|
|
58
|
+
|
|
59
|
+
if (intPart == 0)
|
|
60
|
+
res = "0";
|
|
61
|
+
else
|
|
62
|
+
{
|
|
63
|
+
while (intPart > 0)
|
|
64
|
+
{
|
|
65
|
+
res += chars[intPart % radix];
|
|
66
|
+
intPart /= radix;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
if (negative)
|
|
70
|
+
res += "-";
|
|
71
|
+
std::reverse(res.begin(), res.end());
|
|
72
|
+
return res;
|
|
37
73
|
}
|
|
74
|
+
|
|
38
75
|
}
|
|
39
|
-
if (negative)
|
|
40
|
-
res += "-";
|
|
41
|
-
std::reverse(res.begin(), res.end());
|
|
42
|
-
return res;
|
|
43
|
-
}
|
|
44
76
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
77
|
+
// --- NumberPrototypes Implementation ---
|
|
78
|
+
|
|
79
|
+
namespace NumberPrototypes
|
|
80
|
+
{
|
|
81
|
+
|
|
82
|
+
AnyValue &get_toExponential_fn()
|
|
83
|
+
{
|
|
84
|
+
static AnyValue fn = AnyValue::make_function([](const AnyValue &thisVal, std::span<const AnyValue> args) -> AnyValue
|
|
85
|
+
{
|
|
49
86
|
double self = thisVal.as_double();
|
|
50
87
|
int digits = -1;
|
|
51
88
|
if (!args.empty() && !args[0].is_undefined())
|
|
@@ -69,14 +106,14 @@ AnyValue &get_toExponential_fn()
|
|
|
69
106
|
|
|
70
107
|
std::string res = ss.str();
|
|
71
108
|
return AnyValue::make_string(res); },
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
}
|
|
109
|
+
"toExponential");
|
|
110
|
+
return fn;
|
|
111
|
+
}
|
|
75
112
|
|
|
76
|
-
AnyValue &get_toFixed_fn()
|
|
77
|
-
{
|
|
78
|
-
|
|
79
|
-
|
|
113
|
+
AnyValue &get_toFixed_fn()
|
|
114
|
+
{
|
|
115
|
+
static AnyValue fn = AnyValue::make_function([](const AnyValue &thisVal, std::span<const AnyValue> args) -> AnyValue
|
|
116
|
+
{
|
|
80
117
|
double self = thisVal.as_double();
|
|
81
118
|
int digits = 0;
|
|
82
119
|
if (!args.empty() && !args[0].is_undefined())
|
|
@@ -91,14 +128,14 @@ AnyValue &get_toFixed_fn()
|
|
|
91
128
|
std::ostringstream ss;
|
|
92
129
|
ss << std::fixed << std::setprecision(digits) << self;
|
|
93
130
|
return AnyValue::make_string(ss.str()); },
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
}
|
|
131
|
+
"toFixed");
|
|
132
|
+
return fn;
|
|
133
|
+
}
|
|
97
134
|
|
|
98
|
-
AnyValue &get_toPrecision_fn()
|
|
99
|
-
{
|
|
100
|
-
|
|
101
|
-
|
|
135
|
+
AnyValue &get_toPrecision_fn()
|
|
136
|
+
{
|
|
137
|
+
static AnyValue fn = AnyValue::make_function([](const AnyValue &thisVal, std::span<const AnyValue> args) -> AnyValue
|
|
138
|
+
{
|
|
102
139
|
double self = thisVal.as_double();
|
|
103
140
|
if (args.empty() || args[0].is_undefined())
|
|
104
141
|
{
|
|
@@ -113,14 +150,14 @@ AnyValue &get_toPrecision_fn()
|
|
|
113
150
|
std::ostringstream ss;
|
|
114
151
|
ss << std::setprecision(precision) << self;
|
|
115
152
|
return AnyValue::make_string(ss.str()); },
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
}
|
|
153
|
+
"toPrecision");
|
|
154
|
+
return fn;
|
|
155
|
+
}
|
|
119
156
|
|
|
120
|
-
AnyValue &get_toString_fn()
|
|
121
|
-
{
|
|
122
|
-
|
|
123
|
-
|
|
157
|
+
AnyValue &get_toString_fn()
|
|
158
|
+
{
|
|
159
|
+
static AnyValue fn = AnyValue::make_function([](const AnyValue &thisVal, std::span<const AnyValue> args) -> AnyValue
|
|
160
|
+
{
|
|
124
161
|
double self = thisVal.as_double();
|
|
125
162
|
int radix = 10;
|
|
126
163
|
if (!args.empty() && !args[0].is_undefined())
|
|
@@ -132,45 +169,53 @@ AnyValue &get_toString_fn()
|
|
|
132
169
|
throw Exception::make_exception("toString() radix argument must be between 2 and 36", "RangeError");
|
|
133
170
|
}
|
|
134
171
|
|
|
135
|
-
return AnyValue::make_string(
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
}
|
|
172
|
+
return AnyValue::make_string(JsNumber::to_radix_string(self, radix)); },
|
|
173
|
+
"toString");
|
|
174
|
+
return fn;
|
|
175
|
+
}
|
|
139
176
|
|
|
140
|
-
AnyValue &get_valueOf_fn()
|
|
141
|
-
{
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
}
|
|
177
|
+
AnyValue &get_valueOf_fn()
|
|
178
|
+
{
|
|
179
|
+
static AnyValue fn = AnyValue::make_function([](const AnyValue &thisVal, std::span<const AnyValue>) -> AnyValue
|
|
180
|
+
{ return AnyValue::make_number(thisVal.as_double()); },
|
|
181
|
+
"valueOf");
|
|
182
|
+
return fn;
|
|
183
|
+
}
|
|
147
184
|
|
|
148
|
-
AnyValue &get_toLocaleString_fn()
|
|
149
|
-
{
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
}
|
|
185
|
+
AnyValue &get_toLocaleString_fn()
|
|
186
|
+
{
|
|
187
|
+
static AnyValue fn = AnyValue::make_function([](const AnyValue &thisVal, std::span<const AnyValue>) -> AnyValue
|
|
188
|
+
{ return AnyValue::make_string(AnyValue::make_number(thisVal.as_double()).to_std_string()); },
|
|
189
|
+
"toLocaleString");
|
|
190
|
+
return fn;
|
|
191
|
+
}
|
|
155
192
|
|
|
156
|
-
std::optional<AnyValue> get(const std::string &key)
|
|
157
|
-
{
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
193
|
+
std::optional<AnyValue> get(const std::string &key)
|
|
194
|
+
{
|
|
195
|
+
if (key == "toExponential")
|
|
196
|
+
return get_toExponential_fn();
|
|
197
|
+
if (key == "toFixed")
|
|
198
|
+
return get_toFixed_fn();
|
|
199
|
+
if (key == "toPrecision")
|
|
200
|
+
return get_toPrecision_fn();
|
|
201
|
+
if (key == "toString")
|
|
202
|
+
return get_toString_fn();
|
|
203
|
+
if (key == "valueOf")
|
|
204
|
+
return get_valueOf_fn();
|
|
205
|
+
if (key == "toLocaleString")
|
|
206
|
+
return get_toLocaleString_fn();
|
|
207
|
+
return std::nullopt;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
std::optional<AnyValue> get(const AnyValue &key)
|
|
211
|
+
{
|
|
212
|
+
if (key == "toString" || key == AnyValue::from_symbol(WellKnownSymbols::toStringTag))
|
|
213
|
+
return get_toString_fn();
|
|
214
|
+
if (key == "valueOf")
|
|
215
|
+
return get_valueOf_fn();
|
|
216
|
+
return std::nullopt;
|
|
217
|
+
}
|
|
173
218
|
|
|
174
|
-
} // namespace NumberPrototypes
|
|
219
|
+
} // namespace NumberPrototypes
|
|
175
220
|
|
|
176
221
|
} // namespace jspp
|
|
@@ -2,158 +2,199 @@
|
|
|
2
2
|
#include "values/object.hpp"
|
|
3
3
|
#include "values/prototypes/object.hpp"
|
|
4
4
|
|
|
5
|
-
namespace jspp
|
|
5
|
+
namespace jspp
|
|
6
|
+
{
|
|
6
7
|
|
|
7
|
-
// --- JsObject Implementation ---
|
|
8
|
+
// --- JsObject Implementation ---
|
|
8
9
|
|
|
9
|
-
JsObject::JsObject() : shape(Shape::empty_shape()), proto(Constants::Null) {}
|
|
10
|
+
JsObject::JsObject() : shape(Shape::empty_shape()), proto(Constants::Null) {}
|
|
10
11
|
|
|
11
|
-
JsObject::JsObject(std::initializer_list<std::pair<std::string, AnyValue>> p, AnyValue pr) : proto(pr)
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
12
|
+
JsObject::JsObject(std::initializer_list<std::pair<std::string, AnyValue>> p, AnyValue pr) : proto(pr)
|
|
13
|
+
{
|
|
14
|
+
shape = Shape::empty_shape();
|
|
15
|
+
storage.reserve(p.size());
|
|
16
|
+
for (const auto &pair : p)
|
|
17
|
+
{
|
|
18
|
+
shape = shape->transition(pair.first);
|
|
19
|
+
storage.push_back(pair.second);
|
|
20
|
+
}
|
|
17
21
|
}
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
22
|
+
|
|
23
|
+
JsObject::JsObject(const std::map<std::string, AnyValue> &p, AnyValue pr) : proto(pr)
|
|
24
|
+
{
|
|
25
|
+
shape = Shape::empty_shape();
|
|
26
|
+
storage.reserve(p.size());
|
|
27
|
+
for (const auto &pair : p)
|
|
28
|
+
{
|
|
29
|
+
shape = shape->transition(pair.first);
|
|
30
|
+
storage.push_back(pair.second);
|
|
31
|
+
}
|
|
26
32
|
}
|
|
27
|
-
}
|
|
28
33
|
|
|
29
|
-
std::string JsObject::to_std_string() const
|
|
30
|
-
|
|
31
|
-
|
|
34
|
+
std::string JsObject::to_std_string() const
|
|
35
|
+
{
|
|
36
|
+
return "[Object Object]";
|
|
37
|
+
}
|
|
32
38
|
|
|
33
|
-
bool JsObject::has_property(const std::string &key) const
|
|
34
|
-
|
|
39
|
+
bool JsObject::has_property(const std::string &key) const
|
|
40
|
+
{
|
|
41
|
+
if (deleted_keys.count(key))
|
|
42
|
+
return false;
|
|
35
43
|
|
|
36
|
-
|
|
37
|
-
return true;
|
|
38
|
-
if (!proto.is_null() && !proto.is_undefined()) {
|
|
39
|
-
if (proto.has_property(key))
|
|
44
|
+
if (shape->get_offset(key).has_value())
|
|
40
45
|
return true;
|
|
46
|
+
if (!proto.is_null() && !proto.is_undefined())
|
|
47
|
+
{
|
|
48
|
+
if (proto.has_property(key))
|
|
49
|
+
return true;
|
|
50
|
+
}
|
|
51
|
+
if (ObjectPrototypes::get(key).has_value())
|
|
52
|
+
return true;
|
|
53
|
+
return false;
|
|
41
54
|
}
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
55
|
+
|
|
56
|
+
bool JsObject::has_symbol_property(const AnyValue &key) const
|
|
57
|
+
{
|
|
58
|
+
if (symbol_props.count(key))
|
|
59
|
+
return true;
|
|
60
|
+
if (!proto.is_null() && !proto.is_undefined())
|
|
61
|
+
{
|
|
62
|
+
if (proto.has_property(key))
|
|
63
|
+
return true;
|
|
64
|
+
}
|
|
65
|
+
if (ObjectPrototypes::get(key).has_value())
|
|
66
|
+
return true;
|
|
67
|
+
return false;
|
|
52
68
|
}
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
69
|
+
|
|
70
|
+
AnyValue JsObject::get_property(const std::string &key, const AnyValue &thisVal)
|
|
71
|
+
{
|
|
72
|
+
if (deleted_keys.count(key))
|
|
73
|
+
return Constants::UNDEFINED;
|
|
74
|
+
|
|
75
|
+
auto offset = shape->get_offset(key);
|
|
76
|
+
if (!offset.has_value())
|
|
77
|
+
{
|
|
78
|
+
if (!proto.is_null() && !proto.is_undefined())
|
|
79
|
+
{
|
|
80
|
+
if (proto.has_property(key))
|
|
81
|
+
{
|
|
82
|
+
return proto.get_property_with_receiver(key, thisVal);
|
|
83
|
+
}
|
|
66
84
|
}
|
|
67
|
-
}
|
|
68
85
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
86
|
+
auto proto_it = ObjectPrototypes::get(key);
|
|
87
|
+
if (proto_it.has_value())
|
|
88
|
+
{
|
|
89
|
+
return AnyValue::resolve_property_for_read(proto_it.value(), thisVal, key);
|
|
90
|
+
}
|
|
91
|
+
return Constants::UNDEFINED;
|
|
72
92
|
}
|
|
73
|
-
return
|
|
93
|
+
return AnyValue::resolve_property_for_read(storage[offset.value()], thisVal, key);
|
|
74
94
|
}
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
95
|
+
|
|
96
|
+
AnyValue JsObject::get_symbol_property(const AnyValue &key, const AnyValue &thisVal)
|
|
97
|
+
{
|
|
98
|
+
auto it = symbol_props.find(key);
|
|
99
|
+
if (it == symbol_props.end())
|
|
100
|
+
{
|
|
101
|
+
if (!proto.is_null() && !proto.is_undefined())
|
|
102
|
+
{
|
|
103
|
+
auto res = proto.get_symbol_property_with_receiver(key, thisVal);
|
|
104
|
+
if (!res.is_undefined())
|
|
105
|
+
return res;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
auto proto_it = ObjectPrototypes::get(key);
|
|
109
|
+
if (proto_it.has_value())
|
|
110
|
+
{
|
|
111
|
+
return AnyValue::resolve_property_for_read(proto_it.value(), thisVal, key.to_std_string());
|
|
112
|
+
}
|
|
113
|
+
return Constants::UNDEFINED;
|
|
84
114
|
}
|
|
115
|
+
return AnyValue::resolve_property_for_read(it->second, thisVal, key.to_std_string());
|
|
116
|
+
}
|
|
85
117
|
|
|
118
|
+
AnyValue JsObject::set_property(const std::string &key, const AnyValue &value, const AnyValue &thisVal)
|
|
119
|
+
{
|
|
86
120
|
auto proto_it = ObjectPrototypes::get(key);
|
|
87
|
-
if (proto_it.has_value())
|
|
88
|
-
|
|
121
|
+
if (proto_it.has_value())
|
|
122
|
+
{
|
|
123
|
+
auto proto_value = proto_it.value();
|
|
124
|
+
if (proto_value.is_accessor_descriptor())
|
|
125
|
+
{
|
|
126
|
+
return AnyValue::resolve_property_for_write(proto_value, thisVal, value, key);
|
|
127
|
+
}
|
|
128
|
+
if (proto_value.is_data_descriptor() && !proto_value.as_data_descriptor()->writable)
|
|
129
|
+
{
|
|
130
|
+
return AnyValue::resolve_property_for_write(proto_value, thisVal, value, key);
|
|
131
|
+
}
|
|
89
132
|
}
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
auto proto_value = proto_it.value();
|
|
99
|
-
if (proto_value.is_accessor_descriptor()) {
|
|
100
|
-
return AnyValue::resolve_property_for_write(proto_value, thisVal, value, key);
|
|
133
|
+
|
|
134
|
+
if (deleted_keys.count(key))
|
|
135
|
+
deleted_keys.erase(key);
|
|
136
|
+
|
|
137
|
+
auto offset = shape->get_offset(key);
|
|
138
|
+
if (offset.has_value())
|
|
139
|
+
{
|
|
140
|
+
return AnyValue::resolve_property_for_write(storage[offset.value()], thisVal, value, key);
|
|
101
141
|
}
|
|
102
|
-
|
|
103
|
-
|
|
142
|
+
else
|
|
143
|
+
{
|
|
144
|
+
shape = shape->transition(key);
|
|
145
|
+
storage.push_back(value);
|
|
146
|
+
return value;
|
|
104
147
|
}
|
|
105
148
|
}
|
|
106
149
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
AnyValue JsObject::set_symbol_property(const AnyValue &key, const AnyValue &value, const AnyValue &thisVal) {
|
|
120
|
-
auto it = symbol_props.find(key);
|
|
121
|
-
if (it != symbol_props.end()) {
|
|
122
|
-
return AnyValue::resolve_property_for_write(it->second, thisVal, value, key.to_std_string());
|
|
123
|
-
} else {
|
|
124
|
-
symbol_props[key] = value;
|
|
125
|
-
return value;
|
|
150
|
+
AnyValue JsObject::set_symbol_property(const AnyValue &key, const AnyValue &value, const AnyValue &thisVal)
|
|
151
|
+
{
|
|
152
|
+
auto it = symbol_props.find(key);
|
|
153
|
+
if (it != symbol_props.end())
|
|
154
|
+
{
|
|
155
|
+
return AnyValue::resolve_property_for_write(it->second, thisVal, value, key.to_std_string());
|
|
156
|
+
}
|
|
157
|
+
else
|
|
158
|
+
{
|
|
159
|
+
symbol_props[key] = value;
|
|
160
|
+
return value;
|
|
161
|
+
}
|
|
126
162
|
}
|
|
127
|
-
}
|
|
128
163
|
|
|
129
|
-
// --- ObjectPrototypes Implementation ---
|
|
164
|
+
// --- ObjectPrototypes Implementation ---
|
|
130
165
|
|
|
131
|
-
namespace ObjectPrototypes
|
|
166
|
+
namespace ObjectPrototypes
|
|
167
|
+
{
|
|
132
168
|
|
|
133
|
-
AnyValue&
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
169
|
+
AnyValue &get_toString_fn()
|
|
170
|
+
{
|
|
171
|
+
static AnyValue fn = AnyValue::make_function([](const AnyValue &thisVal, std::span<const AnyValue> _) -> AnyValue
|
|
172
|
+
{ return AnyValue::make_string(thisVal.to_std_string()); },
|
|
173
|
+
"toString");
|
|
174
|
+
return fn;
|
|
175
|
+
}
|
|
139
176
|
|
|
140
|
-
std::optional<AnyValue> get(const std::string &key)
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
}
|
|
177
|
+
std::optional<AnyValue> get(const std::string &key)
|
|
178
|
+
{
|
|
179
|
+
if (key == "toString")
|
|
180
|
+
{
|
|
181
|
+
return get_toString_fn();
|
|
182
|
+
}
|
|
183
|
+
return std::nullopt;
|
|
184
|
+
}
|
|
146
185
|
|
|
147
|
-
std::optional<AnyValue> get(const AnyValue &key)
|
|
148
|
-
|
|
149
|
-
|
|
186
|
+
std::optional<AnyValue> get(const AnyValue &key)
|
|
187
|
+
{
|
|
188
|
+
if (key.is_string())
|
|
189
|
+
return get(key.as_string()->value);
|
|
150
190
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
191
|
+
if (key == AnyValue::from_symbol(WellKnownSymbols::toStringTag))
|
|
192
|
+
{
|
|
193
|
+
return get_toString_fn();
|
|
194
|
+
}
|
|
195
|
+
return std::nullopt;
|
|
196
|
+
}
|
|
156
197
|
|
|
157
|
-
} // namespace ObjectPrototypes
|
|
198
|
+
} // namespace ObjectPrototypes
|
|
158
199
|
|
|
159
200
|
} // namespace jspp
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
#include "types.hpp"
|
|
4
|
+
#include <optional>
|
|
5
|
+
|
|
6
|
+
namespace jspp
|
|
7
|
+
{
|
|
8
|
+
class AnyValue;
|
|
9
|
+
|
|
10
|
+
namespace JsBoolean
|
|
11
|
+
{
|
|
12
|
+
std::string to_std_string(bool value);
|
|
13
|
+
std::string to_std_string(const AnyValue &value);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
namespace BooleanPrototypes
|
|
17
|
+
{
|
|
18
|
+
AnyValue &get_toString_fn();
|
|
19
|
+
AnyValue &get_valueOf_fn();
|
|
20
|
+
|
|
21
|
+
std::optional<AnyValue> get(const std::string &key);
|
|
22
|
+
std::optional<AnyValue> get(const AnyValue &key);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
@@ -7,9 +7,16 @@ namespace jspp
|
|
|
7
7
|
{
|
|
8
8
|
class AnyValue;
|
|
9
9
|
|
|
10
|
+
namespace JsNumber
|
|
11
|
+
{
|
|
12
|
+
std::string to_std_string(double num);
|
|
13
|
+
std::string to_std_string(const AnyValue &value);
|
|
14
|
+
std::string to_radix_string(double value, int radix);
|
|
15
|
+
|
|
16
|
+
}
|
|
17
|
+
|
|
10
18
|
namespace NumberPrototypes
|
|
11
19
|
{
|
|
12
|
-
std::string number_to_radix_string(double value, int radix);
|
|
13
20
|
AnyValue &get_toExponential_fn();
|
|
14
21
|
AnyValue &get_toFixed_fn();
|
|
15
22
|
AnyValue &get_toPrecision_fn();
|
package/dist/cli/file-utils.js
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import fs from "fs/promises";
|
|
2
|
-
import path from "path";
|
|
3
|
-
export async function getLatestMtime(dirPath) {
|
|
4
|
-
let maxMtime = 0;
|
|
5
|
-
const entries = await fs.readdir(dirPath, { withFileTypes: true });
|
|
6
|
-
for (const entry of entries) {
|
|
7
|
-
const fullPath = path.join(dirPath, entry.name);
|
|
8
|
-
if (entry.isDirectory()) {
|
|
9
|
-
const nestedMtime = await getLatestMtime(fullPath);
|
|
10
|
-
if (nestedMtime > maxMtime)
|
|
11
|
-
maxMtime = nestedMtime;
|
|
12
|
-
}
|
|
13
|
-
else {
|
|
14
|
-
const stats = await fs.stat(fullPath);
|
|
15
|
-
if (stats.mtimeMs > maxMtime)
|
|
16
|
-
maxMtime = stats.mtimeMs;
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
return maxMtime;
|
|
20
|
-
}
|