@ugo-studio/jspp 0.1.4 → 0.1.6

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 (71) hide show
  1. package/dist/analysis/scope.js +17 -0
  2. package/dist/analysis/typeAnalyzer.js +7 -1
  3. package/dist/ast/symbols.js +32 -0
  4. package/dist/ast/types.js +0 -6
  5. package/dist/cli-utils/args.js +57 -0
  6. package/dist/cli-utils/colors.js +9 -0
  7. package/dist/cli-utils/file-utils.js +20 -0
  8. package/dist/cli-utils/spinner.js +55 -0
  9. package/dist/cli.js +105 -30
  10. package/dist/core/codegen/class-handlers.js +10 -6
  11. package/dist/core/codegen/control-flow-handlers.js +57 -28
  12. package/dist/core/codegen/declaration-handlers.js +10 -6
  13. package/dist/core/codegen/expression-handlers.js +206 -61
  14. package/dist/core/codegen/function-handlers.js +203 -76
  15. package/dist/core/codegen/helpers.js +125 -28
  16. package/dist/core/codegen/index.js +23 -15
  17. package/dist/core/codegen/literal-handlers.js +15 -6
  18. package/dist/core/codegen/statement-handlers.js +282 -84
  19. package/dist/core/codegen/visitor.js +3 -1
  20. package/package.json +1 -1
  21. package/src/prelude/any_value.hpp +221 -342
  22. package/src/prelude/any_value_access.hpp +168 -81
  23. package/src/prelude/any_value_defines.hpp +74 -35
  24. package/src/prelude/any_value_helpers.hpp +75 -180
  25. package/src/prelude/exception.hpp +1 -0
  26. package/src/prelude/exception_helpers.hpp +4 -4
  27. package/src/prelude/index.hpp +12 -2
  28. package/src/prelude/library/array.hpp +190 -0
  29. package/src/prelude/library/console.hpp +6 -5
  30. package/src/prelude/library/error.hpp +10 -8
  31. package/src/prelude/library/function.hpp +10 -0
  32. package/src/prelude/library/global.hpp +20 -0
  33. package/src/prelude/library/math.hpp +308 -0
  34. package/src/prelude/library/object.hpp +288 -0
  35. package/src/prelude/library/performance.hpp +1 -1
  36. package/src/prelude/library/process.hpp +39 -0
  37. package/src/prelude/library/promise.hpp +57 -55
  38. package/src/prelude/library/symbol.hpp +45 -57
  39. package/src/prelude/library/timer.hpp +6 -6
  40. package/src/prelude/types.hpp +54 -0
  41. package/src/prelude/utils/access.hpp +215 -11
  42. package/src/prelude/utils/assignment_operators.hpp +99 -0
  43. package/src/prelude/utils/log_any_value/array.hpp +8 -8
  44. package/src/prelude/utils/log_any_value/function.hpp +6 -4
  45. package/src/prelude/utils/log_any_value/object.hpp +41 -24
  46. package/src/prelude/utils/log_any_value/primitives.hpp +3 -1
  47. package/src/prelude/utils/operators.hpp +750 -274
  48. package/src/prelude/utils/well_known_symbols.hpp +12 -0
  49. package/src/prelude/values/array.hpp +8 -6
  50. package/src/prelude/values/async_iterator.hpp +79 -0
  51. package/src/prelude/values/descriptors.hpp +2 -2
  52. package/src/prelude/values/function.hpp +72 -62
  53. package/src/prelude/values/helpers/array.hpp +64 -28
  54. package/src/prelude/values/helpers/async_iterator.hpp +275 -0
  55. package/src/prelude/values/helpers/function.hpp +81 -92
  56. package/src/prelude/values/helpers/iterator.hpp +3 -3
  57. package/src/prelude/values/helpers/object.hpp +54 -9
  58. package/src/prelude/values/helpers/promise.hpp +13 -6
  59. package/src/prelude/values/iterator.hpp +1 -1
  60. package/src/prelude/values/object.hpp +10 -3
  61. package/src/prelude/values/promise.hpp +7 -11
  62. package/src/prelude/values/prototypes/array.hpp +851 -12
  63. package/src/prelude/values/prototypes/async_iterator.hpp +50 -0
  64. package/src/prelude/values/prototypes/function.hpp +2 -2
  65. package/src/prelude/values/prototypes/iterator.hpp +5 -5
  66. package/src/prelude/values/prototypes/number.hpp +153 -0
  67. package/src/prelude/values/prototypes/object.hpp +2 -2
  68. package/src/prelude/values/prototypes/promise.hpp +40 -30
  69. package/src/prelude/values/prototypes/string.hpp +28 -28
  70. package/src/prelude/values/prototypes/symbol.hpp +20 -3
  71. package/src/prelude/values/shape.hpp +52 -0
@@ -0,0 +1,50 @@
1
+ #pragma once
2
+
3
+ #include "types.hpp"
4
+ #include "values/async_iterator.hpp"
5
+ #include "any_value.hpp"
6
+ #include "exception.hpp"
7
+ #include "utils/operators.hpp"
8
+
9
+ namespace jspp
10
+ {
11
+ namespace AsyncIteratorPrototypes
12
+ {
13
+ inline std::optional<AnyValue> get(const std::string &key, JsAsyncIterator<AnyValue> *self)
14
+ {
15
+ // --- toString() method ---
16
+ if (key == "toString" || key == WellKnownSymbols::toStringTag->key)
17
+ {
18
+ return AnyValue::make_function([self](const AnyValue &thisVal, std::span<const AnyValue>) -> AnyValue
19
+ { return AnyValue::make_string(self->to_std_string()); },
20
+ key);
21
+ }
22
+ // --- [Symbol.asyncIterator]() method ---
23
+ // For async iterators, the async iterator is itself (similar to sync iterators)
24
+ if (key == WellKnownSymbols::asyncIterator->key)
25
+ {
26
+ // We return 'this'. Since we can't easily create a shared_ptr from raw pointer,
27
+ // we rely on the context to hold the reference or implement better shared_from_this strategy.
28
+ // For now, assume it works like Iterator.
29
+ return AnyValue::make_function([self](const AnyValue &thisVal, std::span<const AnyValue>) -> AnyValue
30
+ {
31
+ // This is slightly dangerous as we create a new shared_ptr from raw.
32
+ // TODO: fix lifetime management
33
+ return thisVal; },
34
+ key);
35
+ }
36
+ // --- next() method ---
37
+ if (key == "next")
38
+ {
39
+ return AnyValue::make_function([self](const AnyValue &thisVal, std::span<const AnyValue> args) -> AnyValue
40
+ {
41
+ AnyValue val = args.empty() ? AnyValue::make_undefined() : args[0];
42
+ auto res = self->next(val);
43
+ return AnyValue::make_promise(res); },
44
+ key);
45
+ }
46
+
47
+ return std::nullopt;
48
+ }
49
+ }
50
+ }
@@ -13,9 +13,9 @@ namespace jspp
13
13
  inline std::optional<AnyValue> get(const std::string &key, JsFunction *self)
14
14
  {
15
15
  // --- toString() method ---
16
- if (key == "toString" )
16
+ if (key == "toString" || key == WellKnownSymbols::toStringTag->key)
17
17
  {
18
- return AnyValue::make_function([self](const AnyValue &thisVal, const std::vector<AnyValue> &_) -> AnyValue
18
+ return AnyValue::make_function([self](const AnyValue &thisVal, std::span<const AnyValue> _) -> AnyValue
19
19
  { return AnyValue::make_string(self->to_std_string()); },
20
20
  key);
21
21
  }
@@ -13,16 +13,16 @@ namespace jspp
13
13
  inline std::optional<AnyValue> get(const std::string &key, JsIterator<AnyValue> *self)
14
14
  {
15
15
  // --- toString() method ---
16
- if (key == "toString" )
16
+ if (key == "toString" || key == WellKnownSymbols::toStringTag->key)
17
17
  {
18
- return AnyValue::make_function([self](const AnyValue &thisVal, const std::vector<AnyValue> &) -> AnyValue
18
+ return AnyValue::make_function([self](const AnyValue &thisVal, std::span<const AnyValue>) -> AnyValue
19
19
  { return AnyValue::make_string(self->to_std_string()); },
20
20
  key);
21
21
  }
22
22
  // --- [Symbol.iterator]() method ---
23
23
  if (key == WellKnownSymbols::iterator->key)
24
24
  {
25
- return AnyValue::make_generator([self](const AnyValue &thisVal, const std::vector<AnyValue> &) -> AnyValue
25
+ return AnyValue::make_generator([self](const AnyValue &thisVal, std::span<const AnyValue>) -> AnyValue
26
26
  {
27
27
  // An iterator's iterator is itself.
28
28
  // We need to return an AnyValue that holds a shared_ptr to this JsIterator.
@@ -37,7 +37,7 @@ namespace jspp
37
37
  // --- next() method ---
38
38
  if (key == "next")
39
39
  {
40
- return AnyValue::make_function([self](const AnyValue &thisVal, const std::vector<AnyValue> &args) -> AnyValue
40
+ return AnyValue::make_function([self](const AnyValue &thisVal, std::span<const AnyValue> args) -> AnyValue
41
41
  {
42
42
  AnyValue val = args.empty() ? AnyValue::make_undefined() : args[0];
43
43
  auto res = self->next(val);
@@ -47,7 +47,7 @@ namespace jspp
47
47
  // --- toArray() method ---
48
48
  if (key == "toArray")
49
49
  {
50
- return AnyValue::make_function([self](const AnyValue &thisVal, const std::vector<AnyValue> &) -> AnyValue
50
+ return AnyValue::make_function([self](const AnyValue &thisVal, std::span<const AnyValue>) -> AnyValue
51
51
  { return AnyValue::make_array(self->to_vector()); },
52
52
  key);
53
53
  }
@@ -0,0 +1,153 @@
1
+ #pragma once
2
+
3
+ #include "types.hpp"
4
+ #include "any_value.hpp"
5
+ #include "exception.hpp"
6
+ #include "utils/operators.hpp"
7
+ #include <string>
8
+ #include <vector>
9
+ #include <iomanip>
10
+ #include <sstream>
11
+ #include <cmath>
12
+ #include <algorithm>
13
+
14
+ namespace jspp
15
+ {
16
+ namespace NumberPrototypes
17
+ {
18
+ // Helper for radix conversion
19
+ inline std::string number_to_radix_string(double value, int radix)
20
+ {
21
+ if (std::isnan(value))
22
+ return "NaN";
23
+ if (!std::isfinite(value))
24
+ return value > 0 ? "Infinity" : "-Infinity";
25
+
26
+ // For radix != 10, we only support integer part for now
27
+ // as implementing full float-to-radix is complex.
28
+ long long intPart = static_cast<long long>(value);
29
+
30
+ if (radix == 10)
31
+ {
32
+ return AnyValue::make_number(value).to_std_string();
33
+ }
34
+
35
+ bool negative = intPart < 0;
36
+ if (negative)
37
+ intPart = -intPart;
38
+
39
+ std::string chars = "0123456789abcdefghijklmnopqrstuvwxyz";
40
+ std::string res = "";
41
+
42
+ if (intPart == 0)
43
+ res = "0";
44
+ else
45
+ {
46
+ while (intPart > 0)
47
+ {
48
+ res += chars[intPart % radix];
49
+ intPart /= radix;
50
+ }
51
+ }
52
+ if (negative)
53
+ res += "-";
54
+ std::reverse(res.begin(), res.end());
55
+ return res;
56
+ }
57
+
58
+ inline std::optional<AnyValue> get(const std::string &key, double self)
59
+ {
60
+ // --- toExponential(fractionDigits) ---
61
+ if (key == "toExponential")
62
+ {
63
+ return AnyValue::make_function([self](const AnyValue &, std::span<const AnyValue> args) -> AnyValue
64
+ {
65
+ int digits = -1;
66
+ if (!args.empty() && !args[0].is_undefined()) {
67
+ digits = Operators_Private::ToInt32(args[0]);
68
+ if (digits < 0 || digits > 100) {
69
+ throw Exception::make_exception("toExponential() digits argument must be between 0 and 100", "RangeError");
70
+ }
71
+ }
72
+
73
+ std::ostringstream ss;
74
+ if (digits >= 0) {
75
+ ss << std::scientific << std::setprecision(digits) << self;
76
+ } else {
77
+ ss << std::scientific << self;
78
+ }
79
+
80
+ std::string res = ss.str();
81
+ return AnyValue::make_string(res); }, "toExponential");
82
+ }
83
+
84
+ // --- toFixed(digits) ---
85
+ if (key == "toFixed")
86
+ {
87
+ return AnyValue::make_function([self](const AnyValue &, std::span<const AnyValue> args) -> AnyValue
88
+ {
89
+ int digits = 0;
90
+ if (!args.empty() && !args[0].is_undefined()) {
91
+ digits = Operators_Private::ToInt32(args[0]);
92
+ }
93
+ if (digits < 0 || digits > 100) {
94
+ throw Exception::make_exception("toFixed() digits argument must be between 0 and 100", "RangeError");
95
+ }
96
+
97
+ std::ostringstream ss;
98
+ ss << std::fixed << std::setprecision(digits) << self;
99
+ return AnyValue::make_string(ss.str()); }, "toFixed");
100
+ }
101
+
102
+ // --- toPrecision(precision) ---
103
+ if (key == "toPrecision")
104
+ {
105
+ return AnyValue::make_function([self](const AnyValue &, std::span<const AnyValue> args) -> AnyValue
106
+ {
107
+ if (args.empty() || args[0].is_undefined()) {
108
+ return AnyValue::make_number(self).get_own_property("toString").call(AnyValue::make_number(self), {}, "toString");
109
+ }
110
+ int precision = Operators_Private::ToInt32(args[0]);
111
+ if (precision < 1 || precision > 100) {
112
+ throw Exception::make_exception("toPrecision() precision argument must be between 1 and 100", "RangeError");
113
+ }
114
+
115
+ std::ostringstream ss;
116
+ ss << std::setprecision(precision) << self;
117
+ return AnyValue::make_string(ss.str()); }, "toPrecision");
118
+ }
119
+
120
+ // --- toString(radix) ---
121
+ if (key == "toString")
122
+ {
123
+ return AnyValue::make_function([self](const AnyValue &, std::span<const AnyValue> args) -> AnyValue
124
+ {
125
+ int radix = 10;
126
+ if (!args.empty() && !args[0].is_undefined()) {
127
+ radix = Operators_Private::ToInt32(args[0]);
128
+ }
129
+ if (radix < 2 || radix > 36) {
130
+ throw Exception::make_exception("toString() radix argument must be between 2 and 36", "RangeError");
131
+ }
132
+
133
+ return AnyValue::make_string(number_to_radix_string(self, radix)); }, "toString");
134
+ }
135
+
136
+ // --- valueOf() ---
137
+ if (key == "valueOf")
138
+ {
139
+ return AnyValue::make_function([self](const AnyValue &, std::span<const AnyValue>) -> AnyValue
140
+ { return AnyValue::make_number(self); }, "valueOf");
141
+ }
142
+
143
+ // --- toLocaleString() ---
144
+ if (key == "toLocaleString")
145
+ {
146
+ return AnyValue::make_function([self](const AnyValue &, std::span<const AnyValue>) -> AnyValue
147
+ { return AnyValue::make_string(AnyValue::make_number(self).to_std_string()); }, "toLocaleString");
148
+ }
149
+
150
+ return std::nullopt;
151
+ }
152
+ }
153
+ }
@@ -13,9 +13,9 @@ namespace jspp
13
13
  inline std::optional<AnyValue> get(const std::string &key, JsObject *self)
14
14
  {
15
15
  // --- toString() method ---
16
- if (key == "toString" )
16
+ if (key == "toString" || key == WellKnownSymbols::toStringTag->key)
17
17
  {
18
- return AnyValue::make_function([self](const AnyValue &thisVal, const std::vector<AnyValue> &_) -> AnyValue
18
+ return AnyValue::make_function([self](const AnyValue &thisVal, std::span<const AnyValue> _) -> AnyValue
19
19
  { return AnyValue::make_string(self->to_std_string()); },
20
20
  key);
21
21
  }
@@ -4,12 +4,17 @@
4
4
  #include "values/promise.hpp"
5
5
  #include "any_value.hpp"
6
6
 
7
- namespace jspp {
8
- namespace PromisePrototypes {
9
- inline std::optional<AnyValue> get(const std::string& key, JsPromise* self) {
10
-
11
- if (key == "then") {
12
- return AnyValue::make_function([self](const AnyValue& thisVal, const std::vector<AnyValue>& args) -> AnyValue {
7
+ namespace jspp
8
+ {
9
+ namespace PromisePrototypes
10
+ {
11
+ inline std::optional<AnyValue> get(const std::string &key, JsPromise *self)
12
+ {
13
+
14
+ if (key == "then")
15
+ {
16
+ return AnyValue::make_function([self](const AnyValue &thisVal, std::span<const AnyValue> args) -> AnyValue
17
+ {
13
18
  AnyValue onFulfilled = (args.size() > 0 && args[0].is_function()) ? args[0] : AnyValue::make_undefined();
14
19
  AnyValue onRejected = (args.size() > 1 && args[1].is_function()) ? args[1] : AnyValue::make_undefined();
15
20
 
@@ -31,16 +36,17 @@ namespace jspp {
31
36
 
32
37
 
33
38
  // Resolve handler
34
- auto resolveHandler = [resolveNew, rejectNew, onFulfilled](AnyValue val) mutable {
39
+ auto resolveHandler = [resolveNew, rejectNew, onFulfilled](const AnyValue& val) mutable {
35
40
  if (onFulfilled.is_function()) {
36
41
  try {
37
- auto res = onFulfilled.as_function()->call(AnyValue::make_undefined(), {val});
42
+ const AnyValue cbArgs[] = {val};
43
+ auto res = onFulfilled.call(AnyValue::make_undefined(), cbArgs, "onFulfilled");
38
44
  if (res.is_promise()) {
39
45
  // Chaining: newPromise follows res
40
46
  auto chained = res.as_promise();
41
47
  chained->then(
42
- [resolveNew](AnyValue v) { resolveNew(v); },
43
- [rejectNew](AnyValue e) { rejectNew(e); }
48
+ [resolveNew](const AnyValue& v) { resolveNew(v); },
49
+ [rejectNew](const AnyValue& e) { rejectNew(e); }
44
50
  );
45
51
  } else {
46
52
  resolveNew(res);
@@ -56,15 +62,16 @@ namespace jspp {
56
62
  };
57
63
 
58
64
  // Reject handler
59
- auto rejectHandler = [resolveNew, rejectNew, onRejected](AnyValue reason) mutable {
65
+ auto rejectHandler = [resolveNew, rejectNew, onRejected](const AnyValue& reason) mutable {
60
66
  if (onRejected.is_function()) {
61
67
  try {
62
- auto res = onRejected.as_function()->call(AnyValue::make_undefined(), {reason});
68
+ const AnyValue cbArgs[] = {reason};
69
+ auto res = onRejected.call(AnyValue::make_undefined(), cbArgs,"onRejected");
63
70
  if (res.is_promise()) {
64
71
  auto chained = res.as_promise();
65
72
  chained->then(
66
- [resolveNew](AnyValue v) { resolveNew(v); },
67
- [rejectNew](AnyValue e) { rejectNew(e); }
73
+ [resolveNew](const AnyValue& v) { resolveNew(v); },
74
+ [rejectNew](const AnyValue& e) { rejectNew(e); }
68
75
  );
69
76
  } else {
70
77
  resolveNew(res); // Recovered
@@ -80,44 +87,47 @@ namespace jspp {
80
87
  };
81
88
 
82
89
  self->then(resolveHandler, rejectHandler);
83
- return newPromiseVal;
84
- }, "then");
90
+ return newPromiseVal; }, "then");
85
91
  }
86
92
 
87
- if (key == "catch") {
88
- return AnyValue::make_function([self](const AnyValue& thisVal, const std::vector<AnyValue>& args) -> AnyValue {
93
+ if (key == "catch")
94
+ {
95
+ return AnyValue::make_function([self](const AnyValue &thisVal, std::span<const AnyValue> args) -> AnyValue
96
+ {
89
97
  // catch(onRejected) is then(undefined, onRejected)
90
98
  AnyValue onRejected = (args.size() > 0 && args[0].is_function()) ? args[0] : AnyValue::make_undefined();
91
- return thisVal.get_own_property("then").as_function()->call(thisVal, {AnyValue::make_undefined(), onRejected});
92
- }, "catch");
99
+ const AnyValue thenArgs[] = {AnyValue::make_undefined(), onRejected};
100
+ return thisVal.get_own_property("then").call(thisVal, thenArgs,"then"); }, "catch");
93
101
  }
94
102
 
95
- if (key == "finally") {
96
- return AnyValue::make_function([self](const AnyValue& thisVal, const std::vector<AnyValue>& args) -> AnyValue {
103
+ if (key == "finally")
104
+ {
105
+ return AnyValue::make_function([self](const AnyValue &thisVal, std::span<const AnyValue> args) -> AnyValue
106
+ {
97
107
  AnyValue onFinally = (args.size() > 0 && args[0].is_function()) ? args[0] : AnyValue::make_undefined();
98
108
 
99
109
  // finally(onFinally) returns a promise that passes through value/reason,
100
110
  // but executes onFinally first.
101
111
 
102
- return thisVal.get_own_property("then").as_function()->call(thisVal, {
103
- AnyValue::make_function([onFinally](const AnyValue&, const std::vector<AnyValue>& args) -> AnyValue {
112
+ const AnyValue thenArgs[] = {
113
+ AnyValue::make_function([onFinally](const AnyValue&, std::span<const AnyValue> args) -> AnyValue {
104
114
  AnyValue val = args.empty() ? AnyValue::make_undefined() : args[0];
105
115
  if (onFinally.is_function()) {
106
- onFinally.as_function()->call(AnyValue::make_undefined(), {});
116
+ onFinally.call(AnyValue::make_undefined(), {}, "onFinally");
107
117
  }
108
118
  return val;
109
119
  }, ""),
110
- AnyValue::make_function([onFinally](const AnyValue&, const std::vector<AnyValue>& args) -> AnyValue {
120
+ AnyValue::make_function([onFinally](const AnyValue&, std::span<const AnyValue> args) -> AnyValue {
111
121
  AnyValue reason = args.empty() ? AnyValue::make_undefined() : args[0];
112
122
  if (onFinally.is_function()) {
113
- onFinally.as_function()->call(AnyValue::make_undefined(), {});
123
+ onFinally.call(AnyValue::make_undefined(), {}, "onFinally");
114
124
  }
115
125
  throw Exception(reason);
116
126
  }, "")
117
- });
118
- }, "finally");
127
+ };
128
+ return thisVal.get_own_property("then").call(thisVal, thenArgs,"then"); }, "finally");
119
129
  }
120
-
130
+
121
131
  return std::nullopt;
122
132
  }
123
133
  }
@@ -19,9 +19,9 @@ namespace jspp
19
19
  inline std::optional<AnyValue> get(const std::string &key, JsString *self)
20
20
  {
21
21
  // --- toString() & valueOf() ---
22
- if (key == "toString" || key == "valueOf")
22
+ if (key == "toString" || key == "valueOf" || key == WellKnownSymbols::toStringTag->key)
23
23
  {
24
- return AnyValue::make_function([self](const AnyValue &thisVal, const std::vector<AnyValue> &args) -> AnyValue
24
+ return AnyValue::make_function([self](const AnyValue &thisVal, std::span<const AnyValue> args) -> AnyValue
25
25
  { return AnyValue::make_string(self->value); },
26
26
  key);
27
27
  }
@@ -29,7 +29,7 @@ namespace jspp
29
29
  // --- [Symbol.iterator]() method ---
30
30
  if (key == WellKnownSymbols::iterator->key)
31
31
  {
32
- return AnyValue::make_generator([self](const AnyValue &thisVal, const std::vector<AnyValue> &_) -> AnyValue
32
+ return AnyValue::make_generator([self](const AnyValue &thisVal, std::span<const AnyValue> _) -> AnyValue
33
33
  { return AnyValue::from_iterator(self->get_iterator()); },
34
34
  key);
35
35
  }
@@ -37,9 +37,9 @@ namespace jspp
37
37
  // --- length property ---
38
38
  if (key == "length")
39
39
  {
40
- return AnyValue::make_accessor_descriptor([self](const AnyValue &thisVal, const std::vector<AnyValue>) -> AnyValue
40
+ return AnyValue::make_accessor_descriptor([self](const AnyValue &thisVal, std::span<const AnyValue>) -> AnyValue
41
41
  { return AnyValue::make_number(self->value.length()); },
42
- [self](const AnyValue &thisVal, const std::vector<AnyValue>) -> AnyValue
42
+ [self](const AnyValue &thisVal, std::span<const AnyValue>) -> AnyValue
43
43
  { return AnyValue::make_undefined(); },
44
44
  false,
45
45
  false);
@@ -48,7 +48,7 @@ namespace jspp
48
48
  // --- charAt(pos) ---
49
49
  if (key == "charAt")
50
50
  {
51
- return AnyValue::make_function([self](const AnyValue &thisVal, const std::vector<AnyValue> &args) -> AnyValue
51
+ return AnyValue::make_function([self](const AnyValue &thisVal, std::span<const AnyValue> args) -> AnyValue
52
52
  {
53
53
  double pos = args.empty() ? 0 : Operators_Private::ToNumber(args[0]);
54
54
  int index = static_cast<int>(pos);
@@ -62,7 +62,7 @@ namespace jspp
62
62
  // --- concat(str1, str2, ...) ---
63
63
  if (key == "concat")
64
64
  {
65
- return AnyValue::make_function([self](const AnyValue &thisVal, const std::vector<AnyValue> &args) -> AnyValue
65
+ return AnyValue::make_function([self](const AnyValue &thisVal, std::span<const AnyValue> args) -> AnyValue
66
66
  {
67
67
  std::string result = self->value;
68
68
  for (const auto& arg : args)
@@ -76,7 +76,7 @@ namespace jspp
76
76
  // --- endsWith(searchString, endPosition) ---
77
77
  if (key == "endsWith")
78
78
  {
79
- return AnyValue::make_function([self](const AnyValue &thisVal, const std::vector<AnyValue> &args) -> AnyValue
79
+ return AnyValue::make_function([self](const AnyValue &thisVal, std::span<const AnyValue> args) -> AnyValue
80
80
  {
81
81
  if(args.empty()) return AnyValue::make_boolean(false);
82
82
  std::string search = args[0].to_std_string();
@@ -92,7 +92,7 @@ namespace jspp
92
92
  // --- includes(searchString, position) ---
93
93
  if (key == "includes")
94
94
  {
95
- return AnyValue::make_function([self](const AnyValue &thisVal, const std::vector<AnyValue> &args) -> AnyValue
95
+ return AnyValue::make_function([self](const AnyValue &thisVal, std::span<const AnyValue> args) -> AnyValue
96
96
  {
97
97
  if(args.empty()) return AnyValue::make_boolean(false);
98
98
  std::string search = args[0].to_std_string();
@@ -105,7 +105,7 @@ namespace jspp
105
105
  // --- indexOf(searchString, position) ---
106
106
  if (key == "indexOf")
107
107
  {
108
- return AnyValue::make_function([self](const AnyValue &thisVal, const std::vector<AnyValue> &args) -> AnyValue
108
+ return AnyValue::make_function([self](const AnyValue &thisVal, std::span<const AnyValue> args) -> AnyValue
109
109
  {
110
110
  if (args.empty()) return AnyValue::make_number(-1);
111
111
  std::string search = args[0].to_std_string();
@@ -118,7 +118,7 @@ namespace jspp
118
118
  // --- lastIndexOf(searchString, position) ---
119
119
  if (key == "lastIndexOf")
120
120
  {
121
- return AnyValue::make_function([self](const AnyValue &thisVal, const std::vector<AnyValue> &args) -> AnyValue
121
+ return AnyValue::make_function([self](const AnyValue &thisVal, std::span<const AnyValue> args) -> AnyValue
122
122
  {
123
123
  if (args.empty()) return AnyValue::make_number(-1);
124
124
  std::string search = args[0].to_std_string();
@@ -131,7 +131,7 @@ namespace jspp
131
131
  // --- padEnd(targetLength, padString) ---
132
132
  if (key == "padEnd")
133
133
  {
134
- return AnyValue::make_function([self](const AnyValue &thisVal, const std::vector<AnyValue> &args) -> AnyValue
134
+ return AnyValue::make_function([self](const AnyValue &thisVal, std::span<const AnyValue> args) -> AnyValue
135
135
  {
136
136
  size_t target_length = args.empty() ? 0 : static_cast<size_t>(Operators_Private::ToNumber(args[0]));
137
137
  if (self->value.length() >= target_length) return AnyValue::make_string(self->value);
@@ -148,7 +148,7 @@ namespace jspp
148
148
  // --- padStart(targetLength, padString) ---
149
149
  if (key == "padStart")
150
150
  {
151
- return AnyValue::make_function([self](const AnyValue &thisVal, const std::vector<AnyValue> &args) -> AnyValue
151
+ return AnyValue::make_function([self](const AnyValue &thisVal, std::span<const AnyValue> args) -> AnyValue
152
152
  {
153
153
  size_t target_length = args.empty() ? 0 : static_cast<size_t>(Operators_Private::ToNumber(args[0]));
154
154
  if (self->value.length() >= target_length) return AnyValue::make_string(self->value);
@@ -165,7 +165,7 @@ namespace jspp
165
165
  // --- repeat(count) ---
166
166
  if (key == "repeat")
167
167
  {
168
- return AnyValue::make_function([self](const AnyValue &thisVal, const std::vector<AnyValue> &args) -> AnyValue
168
+ return AnyValue::make_function([self](const AnyValue &thisVal, std::span<const AnyValue> args) -> AnyValue
169
169
  {
170
170
  double count = args.empty() ? 0 : Operators_Private::ToNumber(args[0]);
171
171
  if (count < 0) {
@@ -184,7 +184,7 @@ namespace jspp
184
184
  // --- replace(substr, newSubstr) ---
185
185
  if (key == "replace")
186
186
  {
187
- return AnyValue::make_function([self](const AnyValue &thisVal, const std::vector<AnyValue> &args) -> AnyValue
187
+ return AnyValue::make_function([self](const AnyValue &thisVal, std::span<const AnyValue> args) -> AnyValue
188
188
  {
189
189
  if (args.size() < 2) return AnyValue::make_string(self->value);
190
190
  std::string search = args[0].to_std_string();
@@ -202,7 +202,7 @@ namespace jspp
202
202
  // --- replaceAll(substr, newSubstr) ---
203
203
  if (key == "replaceAll")
204
204
  {
205
- return AnyValue::make_function([self](const AnyValue &thisVal, const std::vector<AnyValue> &args) -> AnyValue
205
+ return AnyValue::make_function([self](const AnyValue &thisVal, std::span<const AnyValue> args) -> AnyValue
206
206
  {
207
207
  if (args.size() < 2) return AnyValue::make_string(self->value);
208
208
  std::string search = args[0].to_std_string();
@@ -222,7 +222,7 @@ namespace jspp
222
222
  // --- slice(beginIndex, endIndex) ---
223
223
  if (key == "slice")
224
224
  {
225
- return AnyValue::make_function([self](const AnyValue &thisVal, const std::vector<AnyValue> &args) -> AnyValue
225
+ return AnyValue::make_function([self](const AnyValue &thisVal, std::span<const AnyValue> args) -> AnyValue
226
226
  {
227
227
  int len = self->value.length();
228
228
  int start = args.empty() ? 0 : Operators_Private::ToInt32(args[0]);
@@ -242,10 +242,10 @@ namespace jspp
242
242
  // --- split(separator) ---
243
243
  if (key == "split")
244
244
  {
245
- return AnyValue::make_function([self](const AnyValue &thisVal, const std::vector<AnyValue> &args) -> AnyValue
245
+ return AnyValue::make_function([self](const AnyValue &thisVal, std::span<const AnyValue> args) -> AnyValue
246
246
  {
247
247
  std::string separator = (args.empty() || args[0].is_undefined()) ? "" : args[0].to_std_string();
248
- std::vector<std::optional<AnyValue>> result_vec;
248
+ std::vector<jspp::AnyValue> result_vec;
249
249
 
250
250
  if (separator.empty()) {
251
251
  for (char c : (self->value)) {
@@ -260,14 +260,14 @@ namespace jspp
260
260
  }
261
261
  result_vec.push_back(AnyValue::make_string(temp));
262
262
  }
263
- return AnyValue::make_array(result_vec); },
263
+ return AnyValue::make_array(std::move(result_vec)); },
264
264
  key);
265
265
  }
266
266
 
267
267
  // --- startsWith(searchString, position) ---
268
268
  if (key == "startsWith")
269
269
  {
270
- return AnyValue::make_function([self](const AnyValue &thisVal, const std::vector<AnyValue> &args) -> AnyValue
270
+ return AnyValue::make_function([self](const AnyValue &thisVal, std::span<const AnyValue> args) -> AnyValue
271
271
  {
272
272
  if(args.empty()) return AnyValue::make_boolean(false);
273
273
  std::string search = args[0].to_std_string();
@@ -281,7 +281,7 @@ namespace jspp
281
281
  // --- substring(indexStart, indexEnd) ---
282
282
  if (key == "substring")
283
283
  {
284
- return AnyValue::make_function([self](const AnyValue &thisVal, const std::vector<AnyValue> &args) -> AnyValue
284
+ return AnyValue::make_function([self](const AnyValue &thisVal, std::span<const AnyValue> args) -> AnyValue
285
285
  {
286
286
  int len = self->value.length();
287
287
  int start = args.empty() ? 0 : Operators_Private::ToInt32(args[0]);
@@ -302,7 +302,7 @@ namespace jspp
302
302
  // --- toLowerCase() ---
303
303
  if (key == "toLowerCase")
304
304
  {
305
- return AnyValue::make_function([self](const AnyValue &thisVal, const std::vector<AnyValue> &args) -> AnyValue
305
+ return AnyValue::make_function([self](const AnyValue &thisVal, std::span<const AnyValue> args) -> AnyValue
306
306
  {
307
307
  std::string result = self->value;
308
308
  std::transform(result.begin(), result.end(), result.begin(),
@@ -314,7 +314,7 @@ namespace jspp
314
314
  // --- toUpperCase() ---
315
315
  if (key == "toUpperCase")
316
316
  {
317
- return AnyValue::make_function([self](const AnyValue &thisVal, const std::vector<AnyValue> &args) -> AnyValue
317
+ return AnyValue::make_function([self](const AnyValue &thisVal, std::span<const AnyValue> args) -> AnyValue
318
318
  {
319
319
  std::string result = self->value;
320
320
  std::transform(result.begin(), result.end(), result.begin(),
@@ -326,7 +326,7 @@ namespace jspp
326
326
  // --- trim() ---
327
327
  if (key == "trim")
328
328
  {
329
- return AnyValue::make_function([self](const AnyValue &thisVal, const std::vector<AnyValue> &args) -> AnyValue
329
+ return AnyValue::make_function([self](const AnyValue &thisVal, std::span<const AnyValue> args) -> AnyValue
330
330
  {
331
331
  const char* whitespace = " \t\n\r\f\v";
332
332
  std::string result = self->value;
@@ -339,7 +339,7 @@ namespace jspp
339
339
  // --- trimEnd() ---
340
340
  if (key == "trimEnd")
341
341
  {
342
- return AnyValue::make_function([self](const AnyValue &thisVal, const std::vector<AnyValue> &args) -> AnyValue
342
+ return AnyValue::make_function([self](const AnyValue &thisVal, std::span<const AnyValue> args) -> AnyValue
343
343
  {
344
344
  const char* whitespace = " \t\n\r\f\v";
345
345
  std::string result = self->value;
@@ -351,7 +351,7 @@ namespace jspp
351
351
  // --- trimStart() ---
352
352
  if (key == "trimStart")
353
353
  {
354
- return AnyValue::make_function([self](const AnyValue &thisVal, const std::vector<AnyValue> &args) -> AnyValue
354
+ return AnyValue::make_function([self](const AnyValue &thisVal, std::span<const AnyValue> args) -> AnyValue
355
355
  {
356
356
  const char* whitespace = " \t\n\r\f\v";
357
357
  std::string result = self->value;
@@ -363,4 +363,4 @@ namespace jspp
363
363
  return std::nullopt;
364
364
  }
365
365
  }
366
- }
366
+ }