@ugo-studio/jspp 0.3.0 → 0.3.1

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 (95) hide show
  1. package/LICENSE +25 -25
  2. package/README.md +20 -12
  3. package/dist/analysis/scope.js +5 -3
  4. package/dist/analysis/typeAnalyzer.js +21 -25
  5. package/dist/cli/index.js +14 -4
  6. package/dist/cli/utils.js +61 -0
  7. package/dist/core/codegen/control-flow-handlers.js +10 -9
  8. package/dist/core/codegen/declaration-handlers.js +10 -3
  9. package/dist/core/codegen/destructuring-handlers.js +9 -4
  10. package/dist/core/codegen/expression-handlers.js +40 -29
  11. package/dist/core/codegen/function-handlers.js +78 -12
  12. package/dist/core/codegen/helpers.js +91 -14
  13. package/dist/core/codegen/index.js +4 -2
  14. package/dist/core/codegen/statement-handlers.js +8 -6
  15. package/package.json +2 -2
  16. package/scripts/precompile-headers.ts +249 -50
  17. package/scripts/setup-compiler.ts +63 -63
  18. package/src/prelude/any_value.cpp +636 -0
  19. package/src/prelude/any_value.hpp +23 -16
  20. package/src/prelude/{exception_helpers.hpp → exception.cpp} +53 -53
  21. package/src/prelude/exception.hpp +27 -27
  22. package/src/prelude/iterator_instantiations.hpp +10 -0
  23. package/src/prelude/{index.hpp → jspp.hpp} +10 -16
  24. package/src/prelude/library/array.cpp +191 -0
  25. package/src/prelude/library/array.hpp +5 -178
  26. package/src/prelude/library/console.cpp +125 -0
  27. package/src/prelude/library/console.hpp +9 -97
  28. package/src/prelude/library/error.cpp +100 -0
  29. package/src/prelude/library/error.hpp +8 -108
  30. package/src/prelude/library/function.cpp +69 -0
  31. package/src/prelude/library/function.hpp +6 -5
  32. package/src/prelude/library/global.cpp +96 -0
  33. package/src/prelude/library/global.hpp +12 -28
  34. package/src/prelude/library/global_usings.hpp +15 -0
  35. package/src/prelude/library/math.cpp +258 -0
  36. package/src/prelude/library/math.hpp +6 -288
  37. package/src/prelude/library/object.cpp +379 -0
  38. package/src/prelude/library/object.hpp +5 -267
  39. package/src/prelude/library/performance.cpp +21 -0
  40. package/src/prelude/library/performance.hpp +5 -20
  41. package/src/prelude/library/process.cpp +38 -0
  42. package/src/prelude/library/process.hpp +3 -31
  43. package/src/prelude/library/promise.cpp +131 -0
  44. package/src/prelude/library/promise.hpp +5 -116
  45. package/src/prelude/library/symbol.cpp +56 -0
  46. package/src/prelude/library/symbol.hpp +5 -46
  47. package/src/prelude/library/timer.cpp +88 -0
  48. package/src/prelude/library/timer.hpp +11 -87
  49. package/src/prelude/runtime.cpp +19 -0
  50. package/src/prelude/types.hpp +17 -12
  51. package/src/prelude/utils/access.hpp +122 -31
  52. package/src/prelude/utils/assignment_operators.hpp +99 -99
  53. package/src/prelude/utils/log_any_value/array.hpp +61 -40
  54. package/src/prelude/utils/log_any_value/function.hpp +39 -39
  55. package/src/prelude/utils/log_any_value/object.hpp +60 -3
  56. package/src/prelude/utils/operators.hpp +25 -10
  57. package/src/prelude/utils/operators_primitive.hpp +336 -336
  58. package/src/prelude/utils/well_known_symbols.hpp +24 -24
  59. package/src/prelude/values/array.cpp +1399 -0
  60. package/src/prelude/values/array.hpp +4 -0
  61. package/src/prelude/values/async_iterator.cpp +251 -0
  62. package/src/prelude/values/async_iterator.hpp +60 -32
  63. package/src/prelude/values/function.cpp +262 -0
  64. package/src/prelude/values/function.hpp +10 -30
  65. package/src/prelude/values/iterator.cpp +309 -0
  66. package/src/prelude/values/iterator.hpp +33 -64
  67. package/src/prelude/values/number.cpp +176 -0
  68. package/src/prelude/values/object.cpp +159 -0
  69. package/src/prelude/values/object.hpp +4 -0
  70. package/src/prelude/values/promise.cpp +479 -0
  71. package/src/prelude/values/promise.hpp +9 -2
  72. package/src/prelude/values/prototypes/array.hpp +46 -1348
  73. package/src/prelude/values/prototypes/async_iterator.hpp +19 -61
  74. package/src/prelude/values/prototypes/function.hpp +7 -46
  75. package/src/prelude/values/prototypes/iterator.hpp +15 -191
  76. package/src/prelude/values/prototypes/number.hpp +23 -210
  77. package/src/prelude/values/prototypes/object.hpp +7 -23
  78. package/src/prelude/values/prototypes/promise.hpp +8 -186
  79. package/src/prelude/values/prototypes/string.hpp +28 -553
  80. package/src/prelude/values/prototypes/symbol.hpp +9 -70
  81. package/src/prelude/values/shape.hpp +52 -52
  82. package/src/prelude/values/string.cpp +485 -0
  83. package/src/prelude/values/symbol.cpp +89 -0
  84. package/src/prelude/values/symbol.hpp +101 -101
  85. package/src/prelude/any_value_access.hpp +0 -170
  86. package/src/prelude/any_value_defines.hpp +0 -190
  87. package/src/prelude/any_value_helpers.hpp +0 -374
  88. package/src/prelude/values/helpers/array.hpp +0 -199
  89. package/src/prelude/values/helpers/async_iterator.hpp +0 -275
  90. package/src/prelude/values/helpers/function.hpp +0 -109
  91. package/src/prelude/values/helpers/iterator.hpp +0 -145
  92. package/src/prelude/values/helpers/object.hpp +0 -104
  93. package/src/prelude/values/helpers/promise.hpp +0 -254
  94. package/src/prelude/values/helpers/string.hpp +0 -37
  95. package/src/prelude/values/helpers/symbol.hpp +0 -21
@@ -0,0 +1,176 @@
1
+ #include "jspp.hpp"
2
+ #include "values/prototypes/number.hpp"
3
+
4
+ namespace jspp {
5
+
6
+ namespace NumberPrototypes {
7
+
8
+ std::string number_to_radix_string(double value, int radix)
9
+ {
10
+ if (std::isnan(value))
11
+ return "NaN";
12
+ if (!std::isfinite(value))
13
+ return value > 0 ? "Infinity" : "-Infinity";
14
+
15
+ long long intPart = static_cast<long long>(value);
16
+
17
+ if (radix == 10)
18
+ {
19
+ return AnyValue::make_number(value).to_std_string();
20
+ }
21
+
22
+ bool negative = intPart < 0;
23
+ if (negative)
24
+ intPart = -intPart;
25
+
26
+ std::string chars = "0123456789abcdefghijklmnopqrstuvwxyz";
27
+ std::string res = "";
28
+
29
+ if (intPart == 0)
30
+ res = "0";
31
+ else
32
+ {
33
+ while (intPart > 0)
34
+ {
35
+ res += chars[intPart % radix];
36
+ intPart /= radix;
37
+ }
38
+ }
39
+ if (negative)
40
+ res += "-";
41
+ std::reverse(res.begin(), res.end());
42
+ return res;
43
+ }
44
+
45
+ AnyValue &get_toExponential_fn()
46
+ {
47
+ static AnyValue fn = AnyValue::make_function([](const AnyValue &thisVal, std::span<const AnyValue> args) -> AnyValue
48
+ {
49
+ double self = thisVal.as_double();
50
+ int digits = -1;
51
+ if (!args.empty() && !args[0].is_undefined())
52
+ {
53
+ digits = Operators_Private::ToInt32(args[0]);
54
+ if (digits < 0 || digits > 100)
55
+ {
56
+ throw Exception::make_exception("toExponential() digits argument must be between 0 and 100", "RangeError");
57
+ }
58
+ }
59
+
60
+ std::ostringstream ss;
61
+ if (digits >= 0)
62
+ {
63
+ ss << std::scientific << std::setprecision(digits) << self;
64
+ }
65
+ else
66
+ {
67
+ ss << std::scientific << self;
68
+ }
69
+
70
+ std::string res = ss.str();
71
+ return AnyValue::make_string(res); },
72
+ "toExponential");
73
+ return fn;
74
+ }
75
+
76
+ AnyValue &get_toFixed_fn()
77
+ {
78
+ static AnyValue fn = AnyValue::make_function([](const AnyValue &thisVal, std::span<const AnyValue> args) -> AnyValue
79
+ {
80
+ double self = thisVal.as_double();
81
+ int digits = 0;
82
+ if (!args.empty() && !args[0].is_undefined())
83
+ {
84
+ digits = Operators_Private::ToInt32(args[0]);
85
+ }
86
+ if (digits < 0 || digits > 100)
87
+ {
88
+ throw Exception::make_exception("toFixed() digits argument must be between 0 and 100", "RangeError");
89
+ }
90
+
91
+ std::ostringstream ss;
92
+ ss << std::fixed << std::setprecision(digits) << self;
93
+ return AnyValue::make_string(ss.str()); },
94
+ "toFixed");
95
+ return fn;
96
+ }
97
+
98
+ AnyValue &get_toPrecision_fn()
99
+ {
100
+ static AnyValue fn = AnyValue::make_function([](const AnyValue &thisVal, std::span<const AnyValue> args) -> AnyValue
101
+ {
102
+ double self = thisVal.as_double();
103
+ if (args.empty() || args[0].is_undefined())
104
+ {
105
+ return AnyValue::make_number(self).get_own_property("toString").call(AnyValue::make_number(self), {}, "toString");
106
+ }
107
+ int precision = Operators_Private::ToInt32(args[0]);
108
+ if (precision < 1 || precision > 100)
109
+ {
110
+ throw Exception::make_exception("toPrecision() precision argument must be between 1 and 100", "RangeError");
111
+ }
112
+
113
+ std::ostringstream ss;
114
+ ss << std::setprecision(precision) << self;
115
+ return AnyValue::make_string(ss.str()); },
116
+ "toPrecision");
117
+ return fn;
118
+ }
119
+
120
+ AnyValue &get_toString_fn()
121
+ {
122
+ static AnyValue fn = AnyValue::make_function([](const AnyValue &thisVal, std::span<const AnyValue> args) -> AnyValue
123
+ {
124
+ double self = thisVal.as_double();
125
+ int radix = 10;
126
+ if (!args.empty() && !args[0].is_undefined())
127
+ {
128
+ radix = Operators_Private::ToInt32(args[0]);
129
+ }
130
+ if (radix < 2 || radix > 36)
131
+ {
132
+ throw Exception::make_exception("toString() radix argument must be between 2 and 36", "RangeError");
133
+ }
134
+
135
+ return AnyValue::make_string(number_to_radix_string(self, radix)); },
136
+ "toString");
137
+ return fn;
138
+ }
139
+
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
+ }
147
+
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
+ }
155
+
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
+ }
173
+
174
+ } // namespace NumberPrototypes
175
+
176
+ } // namespace jspp
@@ -0,0 +1,159 @@
1
+ #include "jspp.hpp"
2
+ #include "values/object.hpp"
3
+ #include "values/prototypes/object.hpp"
4
+
5
+ namespace jspp {
6
+
7
+ // --- JsObject Implementation ---
8
+
9
+ JsObject::JsObject() : shape(Shape::empty_shape()), proto(Constants::Null) {}
10
+
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);
17
+ }
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);
26
+ }
27
+ }
28
+
29
+ std::string JsObject::to_std_string() const {
30
+ return "[Object Object]";
31
+ }
32
+
33
+ bool JsObject::has_property(const std::string &key) const {
34
+ if (deleted_keys.count(key)) return false;
35
+
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))
40
+ return true;
41
+ }
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;
52
+ }
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);
66
+ }
67
+ }
68
+
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);
72
+ }
73
+ return Constants::UNDEFINED;
74
+ }
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;
84
+ }
85
+
86
+ 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());
89
+ }
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);
101
+ }
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);
104
+ }
105
+ }
106
+
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;
126
+ }
127
+ }
128
+
129
+ // --- ObjectPrototypes Implementation ---
130
+
131
+ namespace ObjectPrototypes {
132
+
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
+ }
139
+
140
+ std::optional<AnyValue> get(const std::string &key) {
141
+ if (key == "toString") {
142
+ return get_toString_fn();
143
+ }
144
+ return std::nullopt;
145
+ }
146
+
147
+ std::optional<AnyValue> get(const AnyValue &key) {
148
+ if (key.is_string())
149
+ return get(key.as_string()->value);
150
+
151
+ if (key == AnyValue::from_symbol(WellKnownSymbols::toStringTag)) {
152
+ return get_toString_fn();
153
+ }
154
+ return std::nullopt;
155
+ }
156
+
157
+ } // namespace ObjectPrototypes
158
+
159
+ } // namespace jspp
@@ -16,6 +16,7 @@ namespace jspp
16
16
  std::vector<AnyValue> storage;
17
17
  AnyValue proto;
18
18
  std::unordered_set<std::string> deleted_keys;
19
+ std::map<AnyValue, AnyValue> symbol_props;
19
20
 
20
21
  JsObject();
21
22
  JsObject(std::initializer_list<std::pair<std::string, AnyValue>> p, AnyValue pr);
@@ -25,7 +26,10 @@ namespace jspp
25
26
 
26
27
  std::string to_std_string() const;
27
28
  bool has_property(const std::string &key) const;
29
+ bool has_symbol_property(const AnyValue &key) const;
28
30
  AnyValue get_property(const std::string &key, const AnyValue &thisVal);
31
+ AnyValue get_symbol_property(const AnyValue &key, const AnyValue &thisVal);
29
32
  AnyValue set_property(const std::string &key, const AnyValue &value, const AnyValue &thisVal);
33
+ AnyValue set_symbol_property(const AnyValue &key, const AnyValue &value, const AnyValue &thisVal);
30
34
  };
31
35
  }