@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.
Files changed (127) hide show
  1. package/LICENSE +25 -25
  2. package/README.md +20 -12
  3. package/dist/cli/args.js +22 -0
  4. package/dist/cli/compiler.js +53 -0
  5. package/dist/cli/index.js +43 -107
  6. package/dist/cli/pch.js +71 -0
  7. package/dist/cli/runner.js +23 -0
  8. package/dist/cli/spinner.js +27 -11
  9. package/dist/cli/transpiler.js +20 -0
  10. package/dist/cli/utils.js +59 -0
  11. package/dist/cli/wasm.js +70 -0
  12. package/dist/index.js +17 -6
  13. package/dist/{analysis → interpreter/analysis}/scope.js +38 -3
  14. package/dist/{analysis → interpreter/analysis}/typeAnalyzer.js +563 -28
  15. package/dist/{core → interpreter/core}/codegen/class-handlers.js +1 -1
  16. package/dist/{core → interpreter/core}/codegen/control-flow-handlers.js +12 -11
  17. package/dist/{core → interpreter/core}/codegen/declaration-handlers.js +28 -9
  18. package/dist/{core → interpreter/core}/codegen/destructuring-handlers.js +9 -4
  19. package/dist/{core → interpreter/core}/codegen/expression-handlers.js +82 -88
  20. package/dist/{core → interpreter/core}/codegen/function-handlers.js +159 -46
  21. package/dist/{core → interpreter/core}/codegen/helpers.js +170 -25
  22. package/dist/interpreter/core/codegen/index.js +156 -0
  23. package/dist/{core → interpreter/core}/codegen/literal-handlers.js +9 -0
  24. package/dist/{core → interpreter/core}/codegen/statement-handlers.js +47 -7
  25. package/package.json +6 -4
  26. package/scripts/precompile-headers.ts +293 -50
  27. package/scripts/setup-compiler.ts +63 -63
  28. package/scripts/setup-emsdk.ts +114 -0
  29. package/src/prelude/any_value.cpp +888 -0
  30. package/src/prelude/any_value.hpp +29 -24
  31. package/src/prelude/{exception_helpers.hpp → exception.cpp} +53 -53
  32. package/src/prelude/exception.hpp +27 -27
  33. package/src/prelude/iterator_instantiations.hpp +10 -0
  34. package/src/prelude/{index.hpp → jspp.hpp} +13 -17
  35. package/src/prelude/library/array.cpp +191 -0
  36. package/src/prelude/library/array.hpp +5 -178
  37. package/src/prelude/library/boolean.cpp +30 -0
  38. package/src/prelude/library/boolean.hpp +14 -0
  39. package/src/prelude/library/console.cpp +125 -0
  40. package/src/prelude/library/console.hpp +9 -97
  41. package/src/prelude/library/error.cpp +100 -0
  42. package/src/prelude/library/error.hpp +8 -108
  43. package/src/prelude/library/function.cpp +69 -0
  44. package/src/prelude/library/function.hpp +6 -5
  45. package/src/prelude/library/global.cpp +98 -0
  46. package/src/prelude/library/global.hpp +12 -28
  47. package/src/prelude/library/global_usings.hpp +15 -0
  48. package/src/prelude/library/math.cpp +261 -0
  49. package/src/prelude/library/math.hpp +8 -288
  50. package/src/prelude/library/object.cpp +379 -0
  51. package/src/prelude/library/object.hpp +5 -267
  52. package/src/prelude/library/performance.cpp +21 -0
  53. package/src/prelude/library/performance.hpp +5 -20
  54. package/src/prelude/library/process.cpp +38 -0
  55. package/src/prelude/library/process.hpp +3 -31
  56. package/src/prelude/library/promise.cpp +131 -0
  57. package/src/prelude/library/promise.hpp +5 -116
  58. package/src/prelude/library/symbol.cpp +56 -0
  59. package/src/prelude/library/symbol.hpp +5 -46
  60. package/src/prelude/library/timer.cpp +88 -0
  61. package/src/prelude/library/timer.hpp +11 -87
  62. package/src/prelude/runtime.cpp +19 -0
  63. package/src/prelude/types.hpp +26 -20
  64. package/src/prelude/utils/access.hpp +123 -32
  65. package/src/prelude/utils/assignment_operators.hpp +119 -99
  66. package/src/prelude/utils/log_any_value/array.hpp +61 -40
  67. package/src/prelude/utils/log_any_value/function.hpp +39 -39
  68. package/src/prelude/utils/log_any_value/log_any_value.hpp +1 -1
  69. package/src/prelude/utils/log_any_value/object.hpp +60 -3
  70. package/src/prelude/utils/log_any_value/primitives.hpp +1 -1
  71. package/src/prelude/utils/operators.hpp +109 -94
  72. package/src/prelude/utils/operators_native.hpp +349 -0
  73. package/src/prelude/utils/well_known_symbols.hpp +24 -24
  74. package/src/prelude/values/array.cpp +1399 -0
  75. package/src/prelude/values/array.hpp +4 -0
  76. package/src/prelude/values/async_iterator.cpp +251 -0
  77. package/src/prelude/values/async_iterator.hpp +60 -32
  78. package/src/prelude/values/boolean.cpp +64 -0
  79. package/src/prelude/values/function.cpp +262 -0
  80. package/src/prelude/values/function.hpp +10 -30
  81. package/src/prelude/values/iterator.cpp +309 -0
  82. package/src/prelude/values/iterator.hpp +33 -64
  83. package/src/prelude/values/number.cpp +221 -0
  84. package/src/prelude/values/object.cpp +200 -0
  85. package/src/prelude/values/object.hpp +4 -0
  86. package/src/prelude/values/promise.cpp +479 -0
  87. package/src/prelude/values/promise.hpp +9 -2
  88. package/src/prelude/values/prototypes/array.hpp +46 -1348
  89. package/src/prelude/values/prototypes/async_iterator.hpp +19 -61
  90. package/src/prelude/values/prototypes/boolean.hpp +24 -0
  91. package/src/prelude/values/prototypes/function.hpp +7 -46
  92. package/src/prelude/values/prototypes/iterator.hpp +15 -191
  93. package/src/prelude/values/prototypes/number.hpp +30 -210
  94. package/src/prelude/values/prototypes/object.hpp +7 -23
  95. package/src/prelude/values/prototypes/promise.hpp +8 -186
  96. package/src/prelude/values/prototypes/string.hpp +28 -553
  97. package/src/prelude/values/prototypes/symbol.hpp +9 -70
  98. package/src/prelude/values/shape.hpp +52 -52
  99. package/src/prelude/values/string.cpp +485 -0
  100. package/src/prelude/values/symbol.cpp +89 -0
  101. package/src/prelude/values/symbol.hpp +101 -101
  102. package/dist/cli/file-utils.js +0 -20
  103. package/dist/cli-utils/args.js +0 -59
  104. package/dist/cli-utils/colors.js +0 -9
  105. package/dist/cli-utils/file-utils.js +0 -20
  106. package/dist/cli-utils/spinner.js +0 -55
  107. package/dist/cli.js +0 -153
  108. package/dist/core/codegen/index.js +0 -86
  109. package/src/prelude/any_value_access.hpp +0 -170
  110. package/src/prelude/any_value_defines.hpp +0 -190
  111. package/src/prelude/any_value_helpers.hpp +0 -374
  112. package/src/prelude/utils/operators_primitive.hpp +0 -337
  113. package/src/prelude/values/helpers/array.hpp +0 -199
  114. package/src/prelude/values/helpers/async_iterator.hpp +0 -275
  115. package/src/prelude/values/helpers/function.hpp +0 -109
  116. package/src/prelude/values/helpers/iterator.hpp +0 -145
  117. package/src/prelude/values/helpers/object.hpp +0 -104
  118. package/src/prelude/values/helpers/promise.hpp +0 -254
  119. package/src/prelude/values/helpers/string.hpp +0 -37
  120. package/src/prelude/values/helpers/symbol.hpp +0 -21
  121. /package/dist/{ast → interpreter/ast}/symbols.js +0 -0
  122. /package/dist/{ast → interpreter/ast}/types.js +0 -0
  123. /package/dist/{core → interpreter/core}/codegen/visitor.js +0 -0
  124. /package/dist/{core → interpreter/core}/constants.js +0 -0
  125. /package/dist/{core → interpreter/core}/error.js +0 -0
  126. /package/dist/{core → interpreter/core}/parser.js +0 -0
  127. /package/dist/{core → interpreter/core}/traverser.js +0 -0
@@ -1,564 +1,39 @@
1
1
  #pragma once
2
2
 
3
3
  #include "types.hpp"
4
- #include "values/string.hpp" // Make sure this is included
5
- #include "any_value.hpp"
6
- #include "utils/operators.hpp"
7
4
  #include <optional>
8
- #include <string>
9
- #include <vector>
10
- #include <algorithm>
11
- #include <cctype>
12
5
 
13
6
  namespace jspp
14
7
  {
8
+ class AnyValue;
9
+
15
10
  namespace StringPrototypes
16
11
  {
17
- inline AnyValue &get_toString_fn()
18
- {
19
- static AnyValue fn = AnyValue::make_function([](const AnyValue &thisVal, std::span<const AnyValue> args) -> AnyValue
20
- { return AnyValue::make_string(thisVal.as_string()->value); },
21
- "toString");
22
- return fn;
23
- }
24
-
25
- inline AnyValue &get_iterator_fn()
26
- {
27
- static AnyValue fn = AnyValue::make_generator([](AnyValue thisVal, std::vector<AnyValue> _) -> jspp::JsIterator<jspp::AnyValue>
28
- {
29
- auto self = thisVal.as_string();
30
- const std::string &value = self->value;
31
- for (size_t i = 0; i < value.length();)
32
- {
33
- unsigned char c = static_cast<unsigned char>(value[i]);
34
- size_t len = 1;
35
- if ((c & 0x80) == 0)
36
- len = 1;
37
- else if ((c & 0xE0) == 0xC0)
38
- len = 2;
39
- else if ((c & 0xF0) == 0xE0)
40
- len = 3;
41
- else if ((c & 0xF8) == 0xF0)
42
- len = 4;
43
-
44
- if (i + len > value.length())
45
- len = value.length() - i;
46
-
47
- co_yield AnyValue::make_string(value.substr(i, len));
48
- i += len;
49
- }
50
- co_return AnyValue::make_undefined(); },
51
- "Symbol.iterator");
52
- return fn;
53
- }
54
-
55
- inline AnyValue &get_length_desc()
56
- {
57
- static auto getter = [](const AnyValue &thisVal, std::span<const AnyValue>) -> AnyValue
58
- { return AnyValue::make_number(thisVal.as_string()->value.length()); };
59
- static auto setter = [](const AnyValue &thisVal, std::span<const AnyValue>) -> AnyValue
60
- { return Constants::UNDEFINED; };
61
- static AnyValue desc = AnyValue::make_accessor_descriptor(getter, setter, false, false);
62
- return desc;
63
- }
64
-
65
- inline AnyValue &get_charAt_fn()
66
- {
67
- static AnyValue fn = AnyValue::make_function([](const AnyValue &thisVal, std::span<const AnyValue> args) -> AnyValue
68
- {
69
- auto self = thisVal.as_string();
70
- double pos = args.empty() ? 0 : Operators_Private::ToNumber(args[0]);
71
- int index = static_cast<int>(pos);
72
- if (index < 0 || index >= self->value.length())
73
- {
74
- return AnyValue::make_string("");
75
- }
76
- return AnyValue::make_string(std::string(1, self->value[index])); },
77
- "charAt");
78
- return fn;
79
- }
80
-
81
- inline AnyValue &get_concat_fn()
82
- {
83
- static AnyValue fn = AnyValue::make_function([](const AnyValue &thisVal, std::span<const AnyValue> args) -> AnyValue
84
- {
85
- std::string result = thisVal.as_string()->value;
86
- for (const auto &arg : args)
87
- {
88
- result += arg.to_std_string();
89
- }
90
- return AnyValue::make_string(result); },
91
- "concat");
92
- return fn;
93
- }
94
-
95
- inline AnyValue &get_endsWith_fn()
96
- {
97
- static AnyValue fn = AnyValue::make_function([](const AnyValue &thisVal, std::span<const AnyValue> args) -> AnyValue
98
- {
99
- auto self = thisVal.as_string();
100
- if (args.empty())
101
- return Constants::FALSE;
102
- std::string search = args[0].to_std_string();
103
- size_t end_pos = (args.size() > 1 && !args[1].is_undefined()) ? static_cast<size_t>(Operators_Private::ToNumber(args[1])) : self->value.length();
104
-
105
- if (end_pos > self->value.length())
106
- end_pos = self->value.length();
107
- if (search.length() > end_pos)
108
- return Constants::FALSE;
109
-
110
- return AnyValue::make_boolean(self->value.substr(end_pos - search.length(), search.length()) == search); },
111
- "endsWith");
112
- return fn;
113
- }
114
-
115
- inline AnyValue &get_includes_fn()
116
- {
117
- static AnyValue fn = AnyValue::make_function([](const AnyValue &thisVal, std::span<const AnyValue> args) -> AnyValue
118
- {
119
- auto self = thisVal.as_string();
120
- if (args.empty())
121
- return Constants::FALSE;
122
- std::string search = args[0].to_std_string();
123
- size_t pos = (args.size() > 1) ? static_cast<size_t>(Operators_Private::ToNumber(args[1])) : 0;
124
-
125
- return AnyValue::make_boolean(self->value.find(search, pos) != std::string::npos); },
126
- "includes");
127
- return fn;
128
- }
129
-
130
- inline AnyValue &get_indexOf_fn()
131
- {
132
- static AnyValue fn = AnyValue::make_function([](const AnyValue &thisVal, std::span<const AnyValue> args) -> AnyValue
133
- {
134
- auto self = thisVal.as_string();
135
- if (args.empty())
136
- return AnyValue::make_number(-1);
137
- std::string search = args[0].to_std_string();
138
- size_t pos = (args.size() > 1) ? static_cast<size_t>(Operators_Private::ToNumber(args[1])) : 0;
139
- size_t result = self->value.find(search, pos);
140
- return result == std::string::npos ? AnyValue::make_number(-1) : AnyValue::make_number(result); },
141
- "indexOf");
142
- return fn;
143
- }
144
-
145
- inline AnyValue &get_lastIndexOf_fn()
146
- {
147
- static AnyValue fn = AnyValue::make_function([](const AnyValue &thisVal, std::span<const AnyValue> args) -> AnyValue
148
- {
149
- auto self = thisVal.as_string();
150
- if (args.empty())
151
- return AnyValue::make_number(-1);
152
- std::string search = args[0].to_std_string();
153
- size_t pos = (args.size() > 1 && !args[1].is_undefined()) ? static_cast<size_t>(Operators_Private::ToNumber(args[1])) : std::string::npos;
154
- size_t result = self->value.rfind(search, pos);
155
- return result == std::string::npos ? AnyValue::make_number(-1) : AnyValue::make_number(result); },
156
- "lastIndexOf");
157
- return fn;
158
- }
159
-
160
- inline AnyValue &get_padEnd_fn()
161
- {
162
- static AnyValue fn = AnyValue::make_function([](const AnyValue &thisVal, std::span<const AnyValue> args) -> AnyValue
163
- {
164
- auto self = thisVal.as_string();
165
- size_t target_length = args.empty() ? 0 : static_cast<size_t>(Operators_Private::ToNumber(args[0]));
166
- if (self->value.length() >= target_length)
167
- return AnyValue::make_string(self->value);
168
- std::string pad_string = (args.size() > 1 && !args[1].is_undefined() && !args[1].to_std_string().empty()) ? args[1].to_std_string() : " ";
169
- std::string result = self->value;
170
- while (result.length() < target_length)
171
- {
172
- result += pad_string;
173
- }
174
- return AnyValue::make_string(result.substr(0, target_length)); },
175
- "padEnd");
176
- return fn;
177
- }
178
-
179
- inline AnyValue &get_padStart_fn()
180
- {
181
- static AnyValue fn = AnyValue::make_function([](const AnyValue &thisVal, std::span<const AnyValue> args) -> AnyValue
182
- {
183
- auto self = thisVal.as_string();
184
- size_t target_length = args.empty() ? 0 : static_cast<size_t>(Operators_Private::ToNumber(args[0]));
185
- if (self->value.length() >= target_length)
186
- return AnyValue::make_string(self->value);
187
- std::string pad_string = (args.size() > 1 && !args[1].is_undefined() && !args[1].to_std_string().empty()) ? args[1].to_std_string() : " ";
188
- std::string padding;
189
- while (padding.length() < target_length - self->value.length())
190
- {
191
- padding += pad_string;
192
- }
193
- return AnyValue::make_string(padding.substr(0, target_length - self->value.length()) + self->value); },
194
- "padStart");
195
- return fn;
196
- }
197
-
198
- inline AnyValue &get_repeat_fn()
199
- {
200
- static AnyValue fn = AnyValue::make_function([](const AnyValue &thisVal, std::span<const AnyValue> args) -> AnyValue
201
- {
202
- auto self = thisVal.as_string();
203
- double count = args.empty() ? 0 : Operators_Private::ToNumber(args[0]);
204
- if (count < 0)
205
- {
206
- // In a real implementation, this should throw a RangeError.
207
- return AnyValue::make_string("");
208
- }
209
- std::string result = "";
210
- for (int i = 0; i < count; ++i)
211
- {
212
- result += self->value;
213
- }
214
- return AnyValue::make_string(result); },
215
- "repeat");
216
- return fn;
217
- }
218
-
219
- inline AnyValue &get_replace_fn()
220
- {
221
- static AnyValue fn = AnyValue::make_function([](const AnyValue &thisVal, std::span<const AnyValue> args) -> AnyValue
222
- {
223
- auto self = thisVal.as_string();
224
- if (args.size() < 2)
225
- return AnyValue::make_string(self->value);
226
- std::string search = args[0].to_std_string();
227
- std::string replacement = args[1].to_std_string();
228
- std::string result = self->value;
229
- size_t pos = result.find(search);
230
- if (pos != std::string::npos)
231
- {
232
- result.replace(pos, search.length(), replacement);
233
- }
234
- return AnyValue::make_string(result); },
235
- "replace");
236
- return fn;
237
- }
238
-
239
- inline AnyValue &get_replaceAll_fn()
240
- {
241
- static AnyValue fn = AnyValue::make_function([](const AnyValue &thisVal, std::span<const AnyValue> args) -> AnyValue
242
- {
243
- auto self = thisVal.as_string();
244
- if (args.size() < 2)
245
- return AnyValue::make_string(self->value);
246
- std::string search = args[0].to_std_string();
247
- if (search.empty())
248
- return AnyValue::make_string(self->value);
249
- std::string replacement = args[1].to_std_string();
250
- std::string result = self->value;
251
- size_t pos = result.find(search);
252
- while (pos != std::string::npos)
253
- {
254
- result.replace(pos, search.length(), replacement);
255
- pos = result.find(search, pos + replacement.length());
256
- }
257
- return AnyValue::make_string(result); },
258
- "replaceAll");
259
- return fn;
260
- }
261
-
262
- inline AnyValue &get_slice_fn()
263
- {
264
- static AnyValue fn = AnyValue::make_function([](const AnyValue &thisVal, std::span<const AnyValue> args) -> AnyValue
265
- {
266
- auto self = thisVal.as_string();
267
- int len = self->value.length();
268
- int start = args.empty() ? 0 : Operators_Private::ToInt32(args[0]);
269
- int end = (args.size() < 2 || args[1].is_undefined()) ? len : Operators_Private::ToInt32(args[1]);
270
-
271
- if (start < 0)
272
- start += len;
273
- if (end < 0)
274
- end += len;
275
-
276
- start = std::max(0, std::min(len, start));
277
- end = std::max(0, std::min(len, end));
278
-
279
- if (start >= end)
280
- return AnyValue::make_string("");
281
- return AnyValue::make_string(self->value.substr(start, end - start)); },
282
- "slice");
283
- return fn;
284
- }
285
-
286
- inline AnyValue &get_split_fn()
287
- {
288
- static AnyValue fn = AnyValue::make_function([](const AnyValue &thisVal, std::span<const AnyValue> args) -> AnyValue
289
- {
290
- auto self = thisVal.as_string();
291
- std::string separator = (args.empty() || args[0].is_undefined()) ? "" : args[0].to_std_string();
292
- std::vector<jspp::AnyValue> result_vec;
293
-
294
- if (separator.empty())
295
- {
296
- for (char c : (self->value))
297
- {
298
- result_vec.push_back(AnyValue::make_string(std::string(1, c)));
299
- }
300
- }
301
- else
302
- {
303
- std::string temp = (self->value);
304
- size_t pos = 0;
305
- while ((pos = temp.find(separator)) != std::string::npos)
306
- {
307
- result_vec.push_back(AnyValue::make_string(temp.substr(0, pos)));
308
- temp.erase(0, pos + separator.length());
309
- }
310
- result_vec.push_back(AnyValue::make_string(temp));
311
- }
312
- return AnyValue::make_array(std::move(result_vec)); },
313
- "split");
314
- return fn;
315
- }
316
-
317
- inline AnyValue &get_startsWith_fn()
318
- {
319
- static AnyValue fn = AnyValue::make_function([](const AnyValue &thisVal, std::span<const AnyValue> args) -> AnyValue
320
- {
321
- auto self = thisVal.as_string();
322
- if (args.empty())
323
- return Constants::FALSE;
324
- std::string search = args[0].to_std_string();
325
- size_t pos = (args.size() > 1) ? static_cast<size_t>(Operators_Private::ToNumber(args[1])) : 0;
326
- if (pos > self->value.length())
327
- pos = self->value.length();
328
-
329
- return AnyValue::make_boolean(self->value.rfind(search, pos) == pos); },
330
- "startsWith");
331
- return fn;
332
- }
333
-
334
- inline AnyValue &get_substring_fn()
335
- {
336
- static AnyValue fn = AnyValue::make_function([](const AnyValue &thisVal, std::span<const AnyValue> args) -> AnyValue
337
- {
338
- auto self = thisVal.as_string();
339
- int len = self->value.length();
340
- int start = args.empty() ? 0 : Operators_Private::ToInt32(args[0]);
341
- int end = (args.size() < 2 || args[1].is_undefined()) ? len : Operators_Private::ToInt32(args[1]);
342
-
343
- start = std::max(0, start);
344
- end = std::max(0, end);
345
-
346
- if (start > end)
347
- std::swap(start, end);
348
-
349
- start = std::min(len, start);
350
- end = std::min(len, end);
351
-
352
- return AnyValue::make_string(self->value.substr(start, end - start)); },
353
- "substring");
354
- return fn;
355
- }
356
-
357
- inline AnyValue &get_toLowerCase_fn()
358
- {
359
- static AnyValue fn = AnyValue::make_function([](const AnyValue &thisVal, std::span<const AnyValue> args) -> AnyValue
360
- {
361
- std::string result = thisVal.as_string()->value;
362
- std::transform(result.begin(), result.end(), result.begin(),
363
- [](unsigned char c)
364
- { return std::tolower(c); });
365
- return AnyValue::make_string(result); },
366
- "toLowerCase");
367
- return fn;
368
- }
369
-
370
- inline AnyValue &get_toUpperCase_fn()
371
- {
372
- static AnyValue fn = AnyValue::make_function([](const AnyValue &thisVal, std::span<const AnyValue> args) -> AnyValue
373
- {
374
- std::string result = thisVal.as_string()->value;
375
- std::transform(result.begin(), result.end(), result.begin(),
376
- [](unsigned char c)
377
- { return std::toupper(c); });
378
- return AnyValue::make_string(result); },
379
- "toUpperCase");
380
- return fn;
381
- }
382
-
383
- inline AnyValue &get_trim_fn()
384
- {
385
- static AnyValue fn = AnyValue::make_function([](const AnyValue &thisVal, std::span<const AnyValue> args) -> AnyValue
386
- {
387
- const char *whitespace = " \t\n\r\f\v";
388
- std::string result = thisVal.as_string()->value;
389
- result.erase(0, result.find_first_not_of(whitespace));
390
- result.erase(result.find_last_not_of(whitespace) + 1);
391
- return AnyValue::make_string(result); },
392
- "trim");
393
- return fn;
394
- }
395
-
396
- inline AnyValue &get_trimEnd_fn()
397
- {
398
- static AnyValue fn = AnyValue::make_function([](const AnyValue &thisVal, std::span<const AnyValue> args) -> AnyValue
399
- {
400
- const char *whitespace = " \t\n\r\f\v";
401
- std::string result = thisVal.as_string()->value;
402
- result.erase(result.find_last_not_of(whitespace) + 1);
403
- return AnyValue::make_string(result); },
404
- "trimEnd");
405
- return fn;
406
- }
407
-
408
- inline AnyValue &get_trimStart_fn()
409
- {
410
- static AnyValue fn = AnyValue::make_function([](const AnyValue &thisVal, std::span<const AnyValue> args) -> AnyValue
411
- {
412
- const char *whitespace = " \t\n\r\f\v";
413
- std::string result = thisVal.as_string()->value;
414
- result.erase(0, result.find_first_not_of(whitespace));
415
- return AnyValue::make_string(result); },
416
- "trimStart");
417
- return fn;
418
- }
419
-
420
- // This function retrieves a prototype method for a given string instance.
421
- inline std::optional<AnyValue> get(const std::string &key)
422
- {
423
- // --- toString() & valueOf() ---
424
- if (key == "toString" || key == "valueOf" || key == WellKnownSymbols::toStringTag->key)
425
- {
426
- return get_toString_fn();
427
- }
428
-
429
- // --- [Symbol.iterator]() method ---
430
- if (key == WellKnownSymbols::iterator->key)
431
- {
432
- return get_iterator_fn();
433
- }
434
-
435
- // --- length property ---
436
- if (key == "length")
437
- {
438
- return get_length_desc();
439
- }
440
-
441
- // --- charAt(pos) ---
442
- if (key == "charAt")
443
- {
444
- return get_charAt_fn();
445
- }
446
-
447
- // --- concat(str1, str2, ...) ---
448
- if (key == "concat")
449
- {
450
- return get_concat_fn();
451
- }
452
-
453
- // --- endsWith(searchString, endPosition) ---
454
- if (key == "endsWith")
455
- {
456
- return get_endsWith_fn();
457
- }
458
-
459
- // --- includes(searchString, position) ---
460
- if (key == "includes")
461
- {
462
- return get_includes_fn();
463
- }
464
-
465
- // --- indexOf(searchString, position) ---
466
- if (key == "indexOf")
467
- {
468
- return get_indexOf_fn();
469
- }
470
-
471
- // --- lastIndexOf(searchString, position) ---
472
- if (key == "lastIndexOf")
473
- {
474
- return get_lastIndexOf_fn();
475
- }
476
-
477
- // --- padEnd(targetLength, padString) ---
478
- if (key == "padEnd")
479
- {
480
- return get_padEnd_fn();
481
- }
482
-
483
- // --- padStart(targetLength, padString) ---
484
- if (key == "padStart")
485
- {
486
- return get_padStart_fn();
487
- }
488
-
489
- // --- repeat(count) ---
490
- if (key == "repeat")
491
- {
492
- return get_repeat_fn();
493
- }
494
-
495
- // --- replace(substr, newSubstr) ---
496
- if (key == "replace")
497
- {
498
- return get_replace_fn();
499
- }
500
-
501
- // --- replaceAll(substr, newSubstr) ---
502
- if (key == "replaceAll")
503
- {
504
- return get_replaceAll_fn();
505
- }
506
-
507
- // --- slice(beginIndex, endIndex) ---
508
- if (key == "slice")
509
- {
510
- return get_slice_fn();
511
- }
512
-
513
- // --- split(separator) ---
514
- if (key == "split")
515
- {
516
- return get_split_fn();
517
- }
518
-
519
- // --- startsWith(searchString, position) ---
520
- if (key == "startsWith")
521
- {
522
- return get_startsWith_fn();
523
- }
524
-
525
- // --- substring(indexStart, indexEnd) ---
526
- if (key == "substring")
527
- {
528
- return get_substring_fn();
529
- }
530
-
531
- // --- toLowerCase() ---
532
- if (key == "toLowerCase")
533
- {
534
- return get_toLowerCase_fn();
535
- }
536
-
537
- // --- toUpperCase() ---
538
- if (key == "toUpperCase")
539
- {
540
- return get_toUpperCase_fn();
541
- }
542
-
543
- // --- trim() ---
544
- if (key == "trim")
545
- {
546
- return get_trim_fn();
547
- }
548
-
549
- // --- trimEnd() ---
550
- if (key == "trimEnd")
551
- {
552
- return get_trimEnd_fn();
553
- }
554
-
555
- // --- trimStart() ---
556
- if (key == "trimStart")
557
- {
558
- return get_trimStart_fn();
559
- }
560
-
561
- return std::nullopt;
562
- }
12
+ AnyValue &get_toString_fn();
13
+ AnyValue &get_iterator_fn();
14
+ AnyValue &get_length_desc();
15
+ AnyValue &get_charAt_fn();
16
+ AnyValue &get_concat_fn();
17
+ AnyValue &get_endsWith_fn();
18
+ AnyValue &get_includes_fn();
19
+ AnyValue &get_indexOf_fn();
20
+ AnyValue &get_lastIndexOf_fn();
21
+ AnyValue &get_padEnd_fn();
22
+ AnyValue &get_padStart_fn();
23
+ AnyValue &get_repeat_fn();
24
+ AnyValue &get_replace_fn();
25
+ AnyValue &get_replaceAll_fn();
26
+ AnyValue &get_slice_fn();
27
+ AnyValue &get_split_fn();
28
+ AnyValue &get_startsWith_fn();
29
+ AnyValue &get_substring_fn();
30
+ AnyValue &get_toLowerCase_fn();
31
+ AnyValue &get_toUpperCase_fn();
32
+ AnyValue &get_trim_fn();
33
+ AnyValue &get_trimEnd_fn();
34
+ AnyValue &get_trimStart_fn();
35
+
36
+ std::optional<AnyValue> get(const std::string &key);
37
+ std::optional<AnyValue> get(const AnyValue &key);
563
38
  }
564
39
  }