@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.
Files changed (64) hide show
  1. package/dist/cli/args.js +22 -0
  2. package/dist/cli/compiler.js +53 -0
  3. package/dist/cli/index.js +43 -117
  4. package/dist/cli/pch.js +71 -0
  5. package/dist/cli/runner.js +23 -0
  6. package/dist/cli/spinner.js +27 -11
  7. package/dist/cli/transpiler.js +20 -0
  8. package/dist/cli/utils.js +25 -27
  9. package/dist/cli/wasm.js +70 -0
  10. package/dist/index.js +17 -6
  11. package/dist/{analysis → interpreter/analysis}/scope.js +34 -1
  12. package/dist/{analysis → interpreter/analysis}/typeAnalyzer.js +542 -3
  13. package/dist/{core → interpreter/core}/codegen/class-handlers.js +1 -1
  14. package/dist/{core → interpreter/core}/codegen/control-flow-handlers.js +2 -2
  15. package/dist/{core → interpreter/core}/codegen/declaration-handlers.js +21 -9
  16. package/dist/{core → interpreter/core}/codegen/destructuring-handlers.js +3 -3
  17. package/dist/{core → interpreter/core}/codegen/expression-handlers.js +44 -61
  18. package/dist/{core → interpreter/core}/codegen/function-handlers.js +108 -61
  19. package/dist/{core → interpreter/core}/codegen/helpers.js +79 -11
  20. package/dist/interpreter/core/codegen/index.js +156 -0
  21. package/dist/{core → interpreter/core}/codegen/literal-handlers.js +9 -0
  22. package/dist/{core → interpreter/core}/codegen/statement-handlers.js +39 -1
  23. package/package.json +6 -4
  24. package/scripts/precompile-headers.ts +63 -19
  25. package/scripts/setup-emsdk.ts +114 -0
  26. package/src/prelude/any_value.cpp +851 -599
  27. package/src/prelude/any_value.hpp +28 -30
  28. package/src/prelude/jspp.hpp +3 -1
  29. package/src/prelude/library/boolean.cpp +30 -0
  30. package/src/prelude/library/boolean.hpp +14 -0
  31. package/src/prelude/library/error.cpp +2 -2
  32. package/src/prelude/library/global.cpp +2 -0
  33. package/src/prelude/library/math.cpp +46 -43
  34. package/src/prelude/library/math.hpp +2 -0
  35. package/src/prelude/library/object.cpp +1 -1
  36. package/src/prelude/types.hpp +10 -9
  37. package/src/prelude/utils/access.hpp +2 -2
  38. package/src/prelude/utils/assignment_operators.hpp +40 -20
  39. package/src/prelude/utils/log_any_value/log_any_value.hpp +1 -1
  40. package/src/prelude/utils/log_any_value/primitives.hpp +1 -1
  41. package/src/prelude/utils/operators.hpp +87 -87
  42. package/src/prelude/utils/operators_native.hpp +349 -0
  43. package/src/prelude/utils/well_known_symbols.hpp +13 -13
  44. package/src/prelude/values/array.cpp +3 -3
  45. package/src/prelude/values/boolean.cpp +64 -0
  46. package/src/prelude/values/number.cpp +137 -92
  47. package/src/prelude/values/object.cpp +163 -122
  48. package/src/prelude/values/prototypes/boolean.hpp +24 -0
  49. package/src/prelude/values/prototypes/number.hpp +8 -1
  50. package/dist/cli/file-utils.js +0 -20
  51. package/dist/cli-utils/args.js +0 -59
  52. package/dist/cli-utils/colors.js +0 -9
  53. package/dist/cli-utils/file-utils.js +0 -20
  54. package/dist/cli-utils/spinner.js +0 -55
  55. package/dist/cli.js +0 -153
  56. package/dist/core/codegen/index.js +0 -88
  57. package/src/prelude/utils/operators_primitive.hpp +0 -337
  58. /package/dist/{ast → interpreter/ast}/symbols.js +0 -0
  59. /package/dist/{ast → interpreter/ast}/types.js +0 -0
  60. /package/dist/{core → interpreter/core}/codegen/visitor.js +0 -0
  61. /package/dist/{core → interpreter/core}/constants.js +0 -0
  62. /package/dist/{core → interpreter/core}/error.js +0 -0
  63. /package/dist/{core → interpreter/core}/parser.js +0 -0
  64. /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
- long long intPart = static_cast<long long>(value);
7
+ // --- JsNumber Implementation ---
16
8
 
17
- if (radix == 10)
9
+ namespace JsNumber
18
10
  {
19
- return AnyValue::make_number(value).to_std_string();
20
- }
21
-
22
- bool negative = intPart < 0;
23
- if (negative)
24
- intPart = -intPart;
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
- std::string chars = "0123456789abcdefghijklmnopqrstuvwxyz";
27
- std::string res = "";
33
+ std::string to_std_string(const AnyValue &value)
34
+ {
35
+ return to_std_string(value.as_double());
36
+ }
28
37
 
29
- if (intPart == 0)
30
- res = "0";
31
- else
32
- {
33
- while (intPart > 0)
38
+ std::string to_radix_string(double value, int radix)
34
39
  {
35
- res += chars[intPart % radix];
36
- intPart /= radix;
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
- AnyValue &get_toExponential_fn()
46
- {
47
- static AnyValue fn = AnyValue::make_function([](const AnyValue &thisVal, std::span<const AnyValue> args) -> AnyValue
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
- "toExponential");
73
- return fn;
74
- }
109
+ "toExponential");
110
+ return fn;
111
+ }
75
112
 
76
- AnyValue &get_toFixed_fn()
77
- {
78
- static AnyValue fn = AnyValue::make_function([](const AnyValue &thisVal, std::span<const AnyValue> args) -> AnyValue
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
- "toFixed");
95
- return fn;
96
- }
131
+ "toFixed");
132
+ return fn;
133
+ }
97
134
 
98
- AnyValue &get_toPrecision_fn()
99
- {
100
- static AnyValue fn = AnyValue::make_function([](const AnyValue &thisVal, std::span<const AnyValue> args) -> AnyValue
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
- "toPrecision");
117
- return fn;
118
- }
153
+ "toPrecision");
154
+ return fn;
155
+ }
119
156
 
120
- AnyValue &get_toString_fn()
121
- {
122
- static AnyValue fn = AnyValue::make_function([](const AnyValue &thisVal, std::span<const AnyValue> args) -> AnyValue
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(number_to_radix_string(self, radix)); },
136
- "toString");
137
- return fn;
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
- static AnyValue fn = AnyValue::make_function([](const AnyValue &thisVal, std::span<const AnyValue>) -> AnyValue
143
- { return AnyValue::make_number(thisVal.as_double()); },
144
- "valueOf");
145
- return fn;
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
- static AnyValue fn = AnyValue::make_function([](const AnyValue &thisVal, std::span<const AnyValue>) -> AnyValue
151
- { return AnyValue::make_string(AnyValue::make_number(thisVal.as_double()).to_std_string()); },
152
- "toLocaleString");
153
- return fn;
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
- if (key == "toExponential") return get_toExponential_fn();
159
- if (key == "toFixed") return get_toFixed_fn();
160
- if (key == "toPrecision") return get_toPrecision_fn();
161
- if (key == "toString") return get_toString_fn();
162
- if (key == "valueOf") return get_valueOf_fn();
163
- if (key == "toLocaleString") return get_toLocaleString_fn();
164
- return std::nullopt;
165
- }
166
-
167
- std::optional<AnyValue> get(const AnyValue &key)
168
- {
169
- if (key == "toString" || key == AnyValue::from_symbol(WellKnownSymbols::toStringTag)) return get_toString_fn();
170
- if (key == "valueOf") return get_valueOf_fn();
171
- return std::nullopt;
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
- shape = Shape::empty_shape();
13
- storage.reserve(p.size());
14
- for (const auto& pair : p) {
15
- shape = shape->transition(pair.first);
16
- storage.push_back(pair.second);
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
- JsObject::JsObject(const std::map<std::string, AnyValue> &p, AnyValue pr) : proto(pr) {
21
- shape = Shape::empty_shape();
22
- storage.reserve(p.size());
23
- for (const auto& pair : p) {
24
- shape = shape->transition(pair.first);
25
- storage.push_back(pair.second);
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
- return "[Object Object]";
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
- if (deleted_keys.count(key)) return false;
39
+ bool JsObject::has_property(const std::string &key) const
40
+ {
41
+ if (deleted_keys.count(key))
42
+ return false;
35
43
 
36
- if (shape->get_offset(key).has_value())
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
- if (ObjectPrototypes::get(key).has_value())
43
- return true;
44
- return false;
45
- }
46
-
47
- bool JsObject::has_symbol_property(const AnyValue &key) const {
48
- if (symbol_props.count(key))
49
- return true;
50
- if (!proto.is_null() && !proto.is_undefined()) {
51
- if (proto.has_property(key)) return true;
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
- if (ObjectPrototypes::get(key).has_value())
54
- return true;
55
- return false;
56
- }
57
-
58
- AnyValue JsObject::get_property(const std::string &key, const AnyValue &thisVal) {
59
- if (deleted_keys.count(key)) return Constants::UNDEFINED;
60
-
61
- auto offset = shape->get_offset(key);
62
- if (!offset.has_value()) {
63
- if (!proto.is_null() && !proto.is_undefined()) {
64
- if (proto.has_property(key)) {
65
- return proto.get_property_with_receiver(key, thisVal);
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
- auto proto_it = ObjectPrototypes::get(key);
70
- if (proto_it.has_value()) {
71
- return AnyValue::resolve_property_for_read(proto_it.value(), thisVal, key);
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 Constants::UNDEFINED;
93
+ return AnyValue::resolve_property_for_read(storage[offset.value()], thisVal, key);
74
94
  }
75
- return AnyValue::resolve_property_for_read(storage[offset.value()], thisVal, key);
76
- }
77
-
78
- AnyValue JsObject::get_symbol_property(const AnyValue &key, const AnyValue &thisVal) {
79
- auto it = symbol_props.find(key);
80
- if (it == symbol_props.end()) {
81
- if (!proto.is_null() && !proto.is_undefined()) {
82
- auto res = proto.get_symbol_property_with_receiver(key, thisVal);
83
- if (!res.is_undefined()) return res;
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
- return AnyValue::resolve_property_for_read(proto_it.value(), thisVal, key.to_std_string());
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
- return Constants::UNDEFINED;
91
- }
92
- return AnyValue::resolve_property_for_read(it->second, thisVal, key.to_std_string());
93
- }
94
-
95
- AnyValue JsObject::set_property(const std::string &key, const AnyValue &value, const AnyValue &thisVal) {
96
- auto proto_it = ObjectPrototypes::get(key);
97
- if (proto_it.has_value()) {
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
- if (proto_value.is_data_descriptor() && !proto_value.as_data_descriptor()->writable) {
103
- return AnyValue::resolve_property_for_write(proto_value, thisVal, value, key);
142
+ else
143
+ {
144
+ shape = shape->transition(key);
145
+ storage.push_back(value);
146
+ return value;
104
147
  }
105
148
  }
106
149
 
107
- if (deleted_keys.count(key)) deleted_keys.erase(key);
108
-
109
- auto offset = shape->get_offset(key);
110
- if (offset.has_value()) {
111
- return AnyValue::resolve_property_for_write(storage[offset.value()], thisVal, value, key);
112
- } else {
113
- shape = shape->transition(key);
114
- storage.push_back(value);
115
- return value;
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& get_toString_fn() {
134
- static AnyValue fn = AnyValue::make_function([](const AnyValue &thisVal, std::span<const AnyValue> _) -> AnyValue
135
- { return AnyValue::make_string(thisVal.to_std_string()); },
136
- "toString");
137
- return fn;
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
- if (key == "toString") {
142
- return get_toString_fn();
143
- }
144
- return std::nullopt;
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
- if (key.is_string())
149
- return get(key.as_string()->value);
186
+ std::optional<AnyValue> get(const AnyValue &key)
187
+ {
188
+ if (key.is_string())
189
+ return get(key.as_string()->value);
150
190
 
151
- if (key == AnyValue::from_symbol(WellKnownSymbols::toStringTag)) {
152
- return get_toString_fn();
153
- }
154
- return std::nullopt;
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();
@@ -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
- }