@ugo-studio/jspp 0.2.5 → 0.2.7

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 (54) hide show
  1. package/README.md +51 -36
  2. package/dist/analysis/scope.js +7 -0
  3. package/dist/analysis/typeAnalyzer.js +96 -43
  4. package/dist/ast/symbols.js +34 -24
  5. package/dist/cli/args.js +59 -0
  6. package/dist/cli/colors.js +9 -0
  7. package/dist/cli/file-utils.js +20 -0
  8. package/dist/cli/index.js +160 -0
  9. package/dist/cli/spinner.js +55 -0
  10. package/dist/core/codegen/class-handlers.js +8 -8
  11. package/dist/core/codegen/control-flow-handlers.js +19 -9
  12. package/dist/core/codegen/declaration-handlers.js +30 -10
  13. package/dist/core/codegen/expression-handlers.js +649 -161
  14. package/dist/core/codegen/function-handlers.js +107 -103
  15. package/dist/core/codegen/helpers.js +61 -14
  16. package/dist/core/codegen/index.js +13 -9
  17. package/dist/core/codegen/literal-handlers.js +4 -2
  18. package/dist/core/codegen/statement-handlers.js +147 -55
  19. package/dist/core/codegen/visitor.js +22 -2
  20. package/dist/core/constants.js +16 -0
  21. package/dist/core/error.js +58 -0
  22. package/dist/index.js +6 -3
  23. package/package.json +3 -3
  24. package/src/prelude/any_value.hpp +89 -59
  25. package/src/prelude/any_value_access.hpp +1 -1
  26. package/src/prelude/any_value_helpers.hpp +85 -43
  27. package/src/prelude/index.hpp +1 -0
  28. package/src/prelude/library/array.hpp +3 -2
  29. package/src/prelude/scheduler.hpp +144 -144
  30. package/src/prelude/types.hpp +8 -8
  31. package/src/prelude/utils/access.hpp +62 -6
  32. package/src/prelude/utils/assignment_operators.hpp +14 -14
  33. package/src/prelude/utils/log_any_value/array.hpp +0 -15
  34. package/src/prelude/utils/log_any_value/object.hpp +12 -10
  35. package/src/prelude/utils/log_any_value/primitives.hpp +2 -0
  36. package/src/prelude/utils/operators.hpp +117 -474
  37. package/src/prelude/utils/operators_primitive.hpp +337 -0
  38. package/src/prelude/values/helpers/array.hpp +4 -4
  39. package/src/prelude/values/helpers/async_iterator.hpp +2 -2
  40. package/src/prelude/values/helpers/function.hpp +3 -3
  41. package/src/prelude/values/helpers/iterator.hpp +2 -2
  42. package/src/prelude/values/helpers/object.hpp +3 -3
  43. package/src/prelude/values/helpers/promise.hpp +1 -1
  44. package/src/prelude/values/helpers/string.hpp +1 -1
  45. package/src/prelude/values/helpers/symbol.hpp +1 -1
  46. package/src/prelude/values/prototypes/array.hpp +1125 -853
  47. package/src/prelude/values/prototypes/async_iterator.hpp +32 -14
  48. package/src/prelude/values/prototypes/function.hpp +30 -18
  49. package/src/prelude/values/prototypes/iterator.hpp +40 -17
  50. package/src/prelude/values/prototypes/number.hpp +119 -62
  51. package/src/prelude/values/prototypes/object.hpp +10 -4
  52. package/src/prelude/values/prototypes/promise.hpp +167 -109
  53. package/src/prelude/values/prototypes/string.hpp +407 -231
  54. package/src/prelude/values/prototypes/symbol.hpp +45 -23
@@ -10,34 +10,52 @@ namespace jspp
10
10
  {
11
11
  namespace AsyncIteratorPrototypes
12
12
  {
13
- inline std::optional<AnyValue> get(const std::string &key, JsAsyncIterator<AnyValue> *self)
13
+ inline AnyValue &get_toString_fn()
14
+ {
15
+ static AnyValue fn = AnyValue::make_function([](const AnyValue &thisVal, std::span<const AnyValue>) -> AnyValue
16
+ { return AnyValue::make_string(thisVal.as_async_iterator()->to_std_string()); },
17
+ "toString");
18
+ return fn;
19
+ }
20
+
21
+ inline AnyValue &get_asyncIterator_fn()
22
+ {
23
+ static AnyValue fn = AnyValue::make_function([](const AnyValue &thisVal, std::span<const AnyValue>) -> AnyValue
24
+ { return thisVal; },
25
+ "Symbol.asyncIterator");
26
+ return fn;
27
+ }
28
+
29
+ inline AnyValue &get_next_fn()
30
+ {
31
+ static AnyValue fn = AnyValue::make_function([](const AnyValue &thisVal, std::span<const AnyValue> args) -> AnyValue
32
+ {
33
+ AnyValue val = args.empty() ? Constants::UNDEFINED : args[0];
34
+ auto res = thisVal.as_async_iterator()->next(val);
35
+ return AnyValue::make_promise(res); },
36
+ "next");
37
+ return fn;
38
+ }
39
+
40
+ inline std::optional<AnyValue> get(const std::string &key)
14
41
  {
15
42
  // --- toString() method ---
16
43
  if (key == "toString" || key == WellKnownSymbols::toStringTag->key)
17
44
  {
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);
45
+ return get_toString_fn();
21
46
  }
22
47
  // --- [Symbol.asyncIterator]() method ---
23
48
  if (key == WellKnownSymbols::asyncIterator->key)
24
49
  {
25
- return AnyValue::make_function([self](const AnyValue &thisVal, std::span<const AnyValue>) -> AnyValue
26
- { return thisVal; },
27
- key);
50
+ return get_asyncIterator_fn();
28
51
  }
29
52
  // --- next() method ---
30
53
  if (key == "next")
31
54
  {
32
- return AnyValue::make_function([self](const AnyValue &thisVal, std::span<const AnyValue> args) -> AnyValue
33
- {
34
- AnyValue val = args.empty() ? Constants::UNDEFINED : args[0];
35
- auto res = self->next(val);
36
- return AnyValue::make_promise(res); },
37
- key);
55
+ return get_next_fn();
38
56
  }
39
57
 
40
58
  return std::nullopt;
41
59
  }
42
60
  }
43
- }
61
+ }
@@ -10,35 +10,47 @@ namespace jspp
10
10
  {
11
11
  namespace FunctionPrototypes
12
12
  {
13
- inline std::optional<AnyValue> get(const std::string &key, JsFunction *self)
13
+ inline AnyValue &get_toString_fn()
14
+ {
15
+ static AnyValue fn = AnyValue::make_function([](const AnyValue &thisVal, std::span<const AnyValue> _) -> AnyValue
16
+ { return AnyValue::make_string(thisVal.as_function()->to_std_string()); },
17
+ "toString");
18
+ return fn;
19
+ }
20
+
21
+ inline AnyValue &get_call_fn()
22
+ {
23
+ static AnyValue fn = AnyValue::make_function([](const AnyValue &thisVal, std::span<const AnyValue> args) -> AnyValue
24
+ {
25
+ AnyValue thisArg = Constants::UNDEFINED;
26
+ std::span<const AnyValue> fnArgs;
27
+
28
+ if (!args.empty())
29
+ {
30
+ thisArg = args[0];
31
+ fnArgs = args.subspan(1);
32
+ }
33
+
34
+ return thisVal.call(thisArg, fnArgs); },
35
+ "call");
36
+ return fn;
37
+ }
38
+
39
+ inline std::optional<AnyValue> get(const std::string &key)
14
40
  {
15
41
  // --- toString() method ---
16
42
  if (key == "toString" || key == WellKnownSymbols::toStringTag->key)
17
43
  {
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);
44
+ return get_toString_fn();
21
45
  }
22
46
 
23
47
  // --- call() method ---
24
48
  if (key == "call")
25
49
  {
26
- return AnyValue::make_function([](const AnyValue &thisVal, std::span<const AnyValue> args) -> AnyValue
27
- {
28
- AnyValue thisArg = Constants::UNDEFINED;
29
- std::span<const AnyValue> fnArgs;
30
-
31
- if (!args.empty())
32
- {
33
- thisArg = args[0];
34
- fnArgs = args.subspan(1);
35
- }
36
-
37
- return thisVal.call(thisArg, fnArgs);
38
- }, key);
50
+ return get_call_fn();
39
51
  }
40
52
 
41
53
  return std::nullopt;
42
54
  }
43
55
  }
44
- }
56
+ }
@@ -10,39 +10,62 @@ namespace jspp
10
10
  {
11
11
  namespace IteratorPrototypes
12
12
  {
13
- inline std::optional<AnyValue> get(const std::string &key, JsIterator<AnyValue> *self)
13
+ inline AnyValue &get_toString_fn()
14
+ {
15
+ static AnyValue fn = AnyValue::make_function([](const AnyValue &thisVal, std::span<const AnyValue>) -> AnyValue
16
+ { return AnyValue::make_string(thisVal.as_iterator()->to_std_string()); },
17
+ "toString");
18
+ return fn;
19
+ }
20
+
21
+ inline AnyValue &get_iterator_fn()
22
+ {
23
+ static AnyValue fn = AnyValue::make_generator([](const AnyValue &thisVal, std::span<const AnyValue>) -> AnyValue
24
+ { return thisVal; },
25
+ "Symbol.iterator");
26
+ return fn;
27
+ }
28
+
29
+ inline AnyValue &get_next_fn()
30
+ {
31
+ static AnyValue fn = AnyValue::make_function([](const AnyValue &thisVal, std::span<const AnyValue> args) -> AnyValue
32
+ {
33
+ AnyValue val = args.empty() ? Constants::UNDEFINED : args[0];
34
+ auto res = thisVal.as_iterator()->next(val);
35
+ return AnyValue::make_object({{"value", res.value.value_or(Constants::UNDEFINED)}, {"done", AnyValue::make_boolean(res.done)}}); },
36
+ "next");
37
+ return fn;
38
+ }
39
+
40
+ inline AnyValue &get_toArray_fn()
41
+ {
42
+ static AnyValue fn = AnyValue::make_function([](const AnyValue &thisVal, std::span<const AnyValue>) -> AnyValue
43
+ { return AnyValue::make_array(thisVal.as_iterator()->to_vector()); },
44
+ "toArray");
45
+ return fn;
46
+ }
47
+
48
+ inline std::optional<AnyValue> get(const std::string &key)
14
49
  {
15
50
  // --- toString() method ---
16
51
  if (key == "toString" || key == WellKnownSymbols::toStringTag->key)
17
52
  {
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);
53
+ return get_toString_fn();
21
54
  }
22
55
  // --- [Symbol.iterator]() method ---
23
56
  if (key == WellKnownSymbols::iterator->key)
24
57
  {
25
- return AnyValue::make_generator([self](const AnyValue &thisVal, std::span<const AnyValue>) -> AnyValue
26
- {
27
- return thisVal; },
28
- key);
58
+ return get_iterator_fn();
29
59
  }
30
60
  // --- next() method ---
31
61
  if (key == "next")
32
62
  {
33
- return AnyValue::make_function([self](const AnyValue &thisVal, std::span<const AnyValue> args) -> AnyValue
34
- {
35
- AnyValue val = args.empty() ? Constants::UNDEFINED : args[0];
36
- auto res = self->next(val);
37
- return AnyValue::make_object({{"value",res.value.value_or(Constants::UNDEFINED)},{"done",AnyValue::make_boolean(res.done)},}); },
38
- key);
63
+ return get_next_fn();
39
64
  }
40
65
  // --- toArray() method ---
41
66
  if (key == "toArray")
42
67
  {
43
- return AnyValue::make_function([self](const AnyValue &thisVal, std::span<const AnyValue>) -> AnyValue
44
- { return AnyValue::make_array(self->to_vector()); },
45
- key);
68
+ return get_toArray_fn();
46
69
  }
47
70
 
48
71
  return std::nullopt;
@@ -55,99 +55,156 @@ namespace jspp
55
55
  return res;
56
56
  }
57
57
 
58
- inline std::optional<AnyValue> get(const std::string &key, double self)
58
+ inline AnyValue &get_toExponential_fn()
59
+ {
60
+ static AnyValue fn = AnyValue::make_function([](const AnyValue &thisVal, std::span<const AnyValue> args) -> AnyValue
61
+ {
62
+ double self = thisVal.as_double();
63
+ int digits = -1;
64
+ if (!args.empty() && !args[0].is_undefined())
65
+ {
66
+ digits = Operators_Private::ToInt32(args[0]);
67
+ if (digits < 0 || digits > 100)
68
+ {
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
+ {
76
+ ss << std::scientific << std::setprecision(digits) << self;
77
+ }
78
+ else
79
+ {
80
+ ss << std::scientific << self;
81
+ }
82
+
83
+ std::string res = ss.str();
84
+ return AnyValue::make_string(res); },
85
+ "toExponential");
86
+ return fn;
87
+ }
88
+
89
+ inline AnyValue &get_toFixed_fn()
90
+ {
91
+ static AnyValue fn = AnyValue::make_function([](const AnyValue &thisVal, std::span<const AnyValue> args) -> AnyValue
92
+ {
93
+ double self = thisVal.as_double();
94
+ int digits = 0;
95
+ if (!args.empty() && !args[0].is_undefined())
96
+ {
97
+ digits = Operators_Private::ToInt32(args[0]);
98
+ }
99
+ if (digits < 0 || digits > 100)
100
+ {
101
+ throw Exception::make_exception("toFixed() digits argument must be between 0 and 100", "RangeError");
102
+ }
103
+
104
+ std::ostringstream ss;
105
+ ss << std::fixed << std::setprecision(digits) << self;
106
+ return AnyValue::make_string(ss.str()); },
107
+ "toFixed");
108
+ return fn;
109
+ }
110
+
111
+ inline AnyValue &get_toPrecision_fn()
112
+ {
113
+ static AnyValue fn = AnyValue::make_function([](const AnyValue &thisVal, std::span<const AnyValue> args) -> AnyValue
114
+ {
115
+ double self = thisVal.as_double();
116
+ if (args.empty() || args[0].is_undefined())
117
+ {
118
+ return AnyValue::make_number(self).get_own_property("toString").call(AnyValue::make_number(self), {}, "toString");
119
+ }
120
+ int precision = Operators_Private::ToInt32(args[0]);
121
+ if (precision < 1 || precision > 100)
122
+ {
123
+ throw Exception::make_exception("toPrecision() precision argument must be between 1 and 100", "RangeError");
124
+ }
125
+
126
+ std::ostringstream ss;
127
+ ss << std::setprecision(precision) << self;
128
+ return AnyValue::make_string(ss.str()); },
129
+ "toPrecision");
130
+ return fn;
131
+ }
132
+
133
+ inline AnyValue &get_toString_fn()
134
+ {
135
+ static AnyValue fn = AnyValue::make_function([](const AnyValue &thisVal, std::span<const AnyValue> args) -> AnyValue
136
+ {
137
+ double self = thisVal.as_double();
138
+ int radix = 10;
139
+ if (!args.empty() && !args[0].is_undefined())
140
+ {
141
+ radix = Operators_Private::ToInt32(args[0]);
142
+ }
143
+ if (radix < 2 || radix > 36)
144
+ {
145
+ throw Exception::make_exception("toString() radix argument must be between 2 and 36", "RangeError");
146
+ }
147
+
148
+ return AnyValue::make_string(number_to_radix_string(self, radix)); },
149
+ "toString");
150
+ return fn;
151
+ }
152
+
153
+ inline AnyValue &get_valueOf_fn()
154
+ {
155
+ static AnyValue fn = AnyValue::make_function([](const AnyValue &thisVal, std::span<const AnyValue>) -> AnyValue
156
+ { return AnyValue::make_number(thisVal.as_double()); },
157
+ "valueOf");
158
+ return fn;
159
+ }
160
+
161
+ inline AnyValue &get_toLocaleString_fn()
162
+ {
163
+ static AnyValue fn = AnyValue::make_function([](const AnyValue &thisVal, std::span<const AnyValue>) -> AnyValue
164
+ { return AnyValue::make_string(AnyValue::make_number(thisVal.as_double()).to_std_string()); },
165
+ "toLocaleString");
166
+ return fn;
167
+ }
168
+
169
+ inline std::optional<AnyValue> get(const std::string &key)
59
170
  {
60
171
  // --- toExponential(fractionDigits) ---
61
172
  if (key == "toExponential")
62
173
  {
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");
174
+ return get_toExponential_fn();
82
175
  }
83
176
 
84
177
  // --- toFixed(digits) ---
85
178
  if (key == "toFixed")
86
179
  {
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");
180
+ return get_toFixed_fn();
100
181
  }
101
182
 
102
183
  // --- toPrecision(precision) ---
103
184
  if (key == "toPrecision")
104
185
  {
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");
186
+ return get_toPrecision_fn();
118
187
  }
119
188
 
120
189
  // --- toString(radix) ---
121
190
  if (key == "toString")
122
191
  {
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");
192
+ return get_toString_fn();
134
193
  }
135
194
 
136
195
  // --- valueOf() ---
137
196
  if (key == "valueOf")
138
197
  {
139
- return AnyValue::make_function([self](const AnyValue &, std::span<const AnyValue>) -> AnyValue
140
- { return AnyValue::make_number(self); }, "valueOf");
198
+ return get_valueOf_fn();
141
199
  }
142
200
 
143
201
  // --- toLocaleString() ---
144
202
  if (key == "toLocaleString")
145
203
  {
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");
204
+ return get_toLocaleString_fn();
148
205
  }
149
206
 
150
207
  return std::nullopt;
151
208
  }
152
209
  }
153
- }
210
+ }
@@ -10,14 +10,20 @@ namespace jspp
10
10
  {
11
11
  namespace ObjectPrototypes
12
12
  {
13
- inline std::optional<AnyValue> get(const std::string &key, JsObject *self)
13
+ inline AnyValue& get_toString_fn()
14
+ {
15
+ static AnyValue fn = AnyValue::make_function([](const AnyValue &thisVal, std::span<const AnyValue> _) -> AnyValue
16
+ { return AnyValue::make_string(thisVal.to_std_string()); },
17
+ "toString");
18
+ return fn;
19
+ }
20
+
21
+ inline std::optional<AnyValue> get(const std::string &key)
14
22
  {
15
23
  // --- toString() method ---
16
24
  if (key == "toString" || key == WellKnownSymbols::toStringTag->key)
17
25
  {
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);
26
+ return get_toString_fn();
21
27
  }
22
28
 
23
29
  return std::nullopt;