@ugo-studio/jspp 0.1.3 → 0.1.5

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 (83) hide show
  1. package/README.md +2 -2
  2. package/dist/analysis/scope.js +33 -4
  3. package/dist/analysis/typeAnalyzer.js +260 -21
  4. package/dist/ast/symbols.js +29 -0
  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 -31
  10. package/dist/core/codegen/class-handlers.js +131 -0
  11. package/dist/core/codegen/control-flow-handlers.js +474 -0
  12. package/dist/core/codegen/declaration-handlers.js +36 -15
  13. package/dist/core/codegen/expression-handlers.js +579 -125
  14. package/dist/core/codegen/function-handlers.js +222 -37
  15. package/dist/core/codegen/helpers.js +158 -4
  16. package/dist/core/codegen/index.js +20 -8
  17. package/dist/core/codegen/literal-handlers.js +18 -6
  18. package/dist/core/codegen/statement-handlers.js +171 -228
  19. package/dist/core/codegen/visitor.js +31 -3
  20. package/package.json +3 -3
  21. package/src/prelude/any_value.hpp +510 -633
  22. package/src/prelude/any_value_access.hpp +151 -0
  23. package/src/prelude/any_value_defines.hpp +190 -0
  24. package/src/prelude/any_value_helpers.hpp +139 -225
  25. package/src/prelude/exception.hpp +32 -0
  26. package/src/prelude/exception_helpers.hpp +49 -0
  27. package/src/prelude/index.hpp +25 -9
  28. package/src/prelude/library/array.hpp +190 -0
  29. package/src/prelude/library/console.hpp +14 -13
  30. package/src/prelude/library/error.hpp +113 -0
  31. package/src/prelude/library/function.hpp +10 -0
  32. package/src/prelude/library/global.hpp +35 -4
  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 +2 -2
  36. package/src/prelude/library/process.hpp +39 -0
  37. package/src/prelude/library/promise.hpp +131 -0
  38. package/src/prelude/library/symbol.hpp +46 -59
  39. package/src/prelude/library/timer.hpp +92 -0
  40. package/src/prelude/scheduler.hpp +145 -0
  41. package/src/prelude/types.hpp +58 -1
  42. package/src/prelude/utils/access.hpp +345 -0
  43. package/src/prelude/utils/assignment_operators.hpp +99 -0
  44. package/src/prelude/utils/log_any_value/array.hpp +245 -0
  45. package/src/prelude/utils/log_any_value/config.hpp +32 -0
  46. package/src/prelude/utils/log_any_value/function.hpp +39 -0
  47. package/src/prelude/utils/log_any_value/fwd.hpp +15 -0
  48. package/src/prelude/utils/log_any_value/helpers.hpp +62 -0
  49. package/src/prelude/utils/log_any_value/log_any_value.hpp +94 -0
  50. package/src/prelude/utils/log_any_value/object.hpp +136 -0
  51. package/src/prelude/utils/log_any_value/primitives.hpp +43 -0
  52. package/src/prelude/utils/operators.hpp +751 -0
  53. package/src/prelude/utils/well_known_symbols.hpp +25 -0
  54. package/src/prelude/values/array.hpp +10 -7
  55. package/src/prelude/{descriptors.hpp → values/descriptors.hpp} +2 -2
  56. package/src/prelude/values/function.hpp +85 -51
  57. package/src/prelude/values/helpers/array.hpp +80 -35
  58. package/src/prelude/values/helpers/function.hpp +110 -77
  59. package/src/prelude/values/helpers/iterator.hpp +16 -10
  60. package/src/prelude/values/helpers/object.hpp +85 -10
  61. package/src/prelude/values/helpers/promise.hpp +181 -0
  62. package/src/prelude/values/helpers/string.hpp +3 -3
  63. package/src/prelude/values/helpers/symbol.hpp +2 -2
  64. package/src/prelude/values/iterator.hpp +14 -6
  65. package/src/prelude/values/object.hpp +14 -3
  66. package/src/prelude/values/promise.hpp +73 -0
  67. package/src/prelude/values/prototypes/array.hpp +855 -16
  68. package/src/prelude/values/prototypes/function.hpp +4 -4
  69. package/src/prelude/values/prototypes/iterator.hpp +11 -10
  70. package/src/prelude/values/prototypes/number.hpp +153 -0
  71. package/src/prelude/values/prototypes/object.hpp +26 -0
  72. package/src/prelude/values/prototypes/promise.hpp +134 -0
  73. package/src/prelude/values/prototypes/string.hpp +29 -29
  74. package/src/prelude/values/prototypes/symbol.hpp +22 -3
  75. package/src/prelude/values/shape.hpp +52 -0
  76. package/src/prelude/values/string.hpp +1 -1
  77. package/src/prelude/values/symbol.hpp +1 -1
  78. package/src/prelude/access.hpp +0 -91
  79. package/src/prelude/error.hpp +0 -31
  80. package/src/prelude/error_helpers.hpp +0 -59
  81. package/src/prelude/log_string.hpp +0 -407
  82. package/src/prelude/operators.hpp +0 -256
  83. package/src/prelude/well_known_symbols.hpp +0 -14
@@ -11,12 +11,14 @@ std::string jspp::JsIterator<T>::to_std_string() const
11
11
  }
12
12
 
13
13
  template <typename T>
14
- jspp::JsIterator<T>::NextResult jspp::JsIterator<T>::next()
14
+ jspp::JsIterator<T>::NextResult jspp::JsIterator<T>::next(const T &val)
15
15
  {
16
16
  // If the generator is already finished or invalid, return {undefined, true}
17
17
  if (!handle || handle.done())
18
18
  return {std::nullopt, true};
19
19
 
20
+ handle.promise().input_value = val;
21
+
20
22
  // Resume execution until next co_yield or co_return
21
23
  handle.resume();
22
24
 
@@ -33,9 +35,9 @@ jspp::JsIterator<T>::NextResult jspp::JsIterator<T>::next()
33
35
  }
34
36
 
35
37
  template <typename T>
36
- std::vector<std::optional<T>> jspp::JsIterator<T>::to_vector()
38
+ std::vector<T> jspp::JsIterator<T>::to_vector()
37
39
  {
38
- std::vector<std::optional<AnyValue>> result;
40
+ std::vector<T> result;
39
41
  while (true)
40
42
  {
41
43
  auto next = this->next();
@@ -43,13 +45,13 @@ std::vector<std::optional<T>> jspp::JsIterator<T>::to_vector()
43
45
  {
44
46
  break;
45
47
  }
46
- result.push_back(next.value);
48
+ result.push_back(next.value.value_or(AnyValue::make_undefined()));
47
49
  }
48
50
  return result;
49
51
  }
50
52
 
51
53
  template <typename T>
52
- jspp::AnyValue jspp::JsIterator<T>::get_property(const std::string &key)
54
+ jspp::AnyValue jspp::JsIterator<T>::get_property(const std::string &key, const AnyValue &thisVal)
53
55
  {
54
56
  auto it = props.find(key);
55
57
  if (it == props.end())
@@ -60,18 +62,18 @@ jspp::AnyValue jspp::JsIterator<T>::get_property(const std::string &key)
60
62
  auto proto_it = IteratorPrototypes::get(key, this);
61
63
  if (proto_it.has_value())
62
64
  {
63
- return AnyValue::resolve_property_for_read(proto_it.value());
65
+ return AnyValue::resolve_property_for_read(proto_it.value(), thisVal, key);
64
66
  }
65
67
  }
66
68
  // prototype not found
67
69
  return jspp::AnyValue::make_undefined();
68
70
  }
69
71
 
70
- return jspp::AnyValue::resolve_property_for_read(it->second);
72
+ return jspp::AnyValue::resolve_property_for_read(it->second, thisVal, key);
71
73
  }
72
74
 
73
75
  template <typename T>
74
- jspp::AnyValue jspp::JsIterator<T>::set_property(const std::string &key, const AnyValue &value)
76
+ jspp::AnyValue jspp::JsIterator<T>::set_property(const std::string &key, const AnyValue &value, const AnyValue &thisVal)
75
77
  {
76
78
  // set prototype property if accessor descriptor
77
79
  if constexpr (std::is_same_v<T, AnyValue>)
@@ -82,7 +84,11 @@ jspp::AnyValue jspp::JsIterator<T>::set_property(const std::string &key, const A
82
84
  auto proto_value = proto_it.value();
83
85
  if (proto_value.is_accessor_descriptor())
84
86
  {
85
- return AnyValue::resolve_property_for_write(proto_it.value(), value);
87
+ return AnyValue::resolve_property_for_write(proto_value, thisVal, value, key);
88
+ }
89
+ if (proto_value.is_data_descriptor() && !proto_value.as_data_descriptor()->writable)
90
+ {
91
+ return AnyValue::resolve_property_for_write(proto_value, thisVal, value, key);
86
92
  }
87
93
  }
88
94
  }
@@ -91,7 +97,7 @@ jspp::AnyValue jspp::JsIterator<T>::set_property(const std::string &key, const A
91
97
  auto it = props.find(key);
92
98
  if (it != props.end())
93
99
  {
94
- return jspp::AnyValue::resolve_property_for_write(it->second, value);
100
+ return jspp::AnyValue::resolve_property_for_write(it->second, thisVal, value, key);
95
101
  }
96
102
  else
97
103
  {
@@ -4,31 +4,106 @@
4
4
  #include "values/object.hpp"
5
5
  #include "any_value.hpp"
6
6
 
7
+ namespace jspp {
8
+ JsObject::JsObject() : shape(Shape::empty_shape()), proto(nullptr) {}
9
+
10
+ JsObject::JsObject(std::initializer_list<std::pair<std::string, AnyValue>> p, std::shared_ptr<AnyValue> pr) : proto(pr) {
11
+ shape = Shape::empty_shape();
12
+ storage.reserve(p.size());
13
+ for (const auto& pair : p) {
14
+ shape = shape->transition(pair.first);
15
+ storage.push_back(pair.second);
16
+ }
17
+ }
18
+
19
+ JsObject::JsObject(const std::map<std::string, AnyValue> &p, std::shared_ptr<AnyValue> pr) : proto(pr) {
20
+ shape = Shape::empty_shape();
21
+ storage.reserve(p.size());
22
+ for (const auto& pair : p) {
23
+ shape = shape->transition(pair.first);
24
+ storage.push_back(pair.second);
25
+ }
26
+ }
27
+ }
28
+
7
29
  std::string jspp::JsObject::to_std_string() const
8
30
  {
9
31
  return "[Object Object]";
10
32
  }
11
33
 
12
- jspp::AnyValue jspp::JsObject::get_property(const std::string &key)
34
+ bool jspp::JsObject::has_property(const std::string &key) const
35
+ {
36
+ if (deleted_keys.count(key)) return false;
37
+
38
+ if (shape->get_offset(key).has_value())
39
+ return true;
40
+ if (proto && !(*proto).is_null() && !(*proto).is_undefined())
41
+ {
42
+ if ((*proto).has_property(key))
43
+ return true;
44
+ }
45
+ if (ObjectPrototypes::get(key, const_cast<JsObject *>(this)).has_value())
46
+ return true;
47
+ return false;
48
+ }
49
+
50
+ jspp::AnyValue jspp::JsObject::get_property(const std::string &key, const AnyValue &thisVal)
13
51
  {
14
- auto it = props.find(key);
15
- if (it != props.end())
52
+ if (deleted_keys.count(key)) return AnyValue::make_undefined();
53
+
54
+ auto offset = shape->get_offset(key);
55
+ if (!offset.has_value())
16
56
  {
17
- return jspp::AnyValue::resolve_property_for_read(it->second);
57
+ // check prototype chain
58
+ if (proto && !(*proto).is_null() && !(*proto).is_undefined())
59
+ {
60
+ if ((*proto).has_property(key))
61
+ {
62
+ return (*proto).get_property_with_receiver(key, thisVal);
63
+ }
64
+ }
65
+
66
+ // check built-in prototype methods (Object.prototype)
67
+ auto proto_it = ObjectPrototypes::get(key, this);
68
+ if (proto_it.has_value())
69
+ {
70
+ return AnyValue::resolve_property_for_read(proto_it.value(), thisVal, key);
71
+ }
72
+ // not found
73
+ return AnyValue::make_undefined();
18
74
  }
19
- return jspp::AnyValue::make_undefined();
75
+ return AnyValue::resolve_property_for_read(storage[offset.value()], thisVal, key);
20
76
  }
21
77
 
22
- jspp::AnyValue jspp::JsObject::set_property(const std::string &key, const AnyValue &value)
78
+ jspp::AnyValue jspp::JsObject::set_property(const std::string &key, const AnyValue &value, const AnyValue &thisVal)
23
79
  {
24
- auto it = props.find(key);
25
- if (it != props.end())
80
+ // set prototype property if accessor descriptor
81
+ auto proto_it = ObjectPrototypes::get(key, this);
82
+ if (proto_it.has_value())
83
+ {
84
+ auto proto_value = proto_it.value();
85
+ if (proto_value.is_accessor_descriptor())
86
+ {
87
+ return AnyValue::resolve_property_for_write(proto_value, thisVal, value, key);
88
+ }
89
+ if (proto_value.is_data_descriptor() && !proto_value.as_data_descriptor()->writable)
90
+ {
91
+ return AnyValue::resolve_property_for_write(proto_value, thisVal, value, key);
92
+ }
93
+ }
94
+
95
+ // set own property
96
+ if (deleted_keys.count(key)) deleted_keys.erase(key);
97
+
98
+ auto offset = shape->get_offset(key);
99
+ if (offset.has_value())
26
100
  {
27
- return jspp::AnyValue::resolve_property_for_write(it->second, value);
101
+ return AnyValue::resolve_property_for_write(storage[offset.value()], thisVal, value, key);
28
102
  }
29
103
  else
30
104
  {
31
- props[key] = value;
105
+ shape = shape->transition(key);
106
+ storage.push_back(value);
32
107
  return value;
33
108
  }
34
109
  }
@@ -0,0 +1,181 @@
1
+ #pragma once
2
+
3
+ #include "types.hpp"
4
+ #include "values/promise.hpp"
5
+ #include "any_value.hpp"
6
+ #include "values/prototypes/promise.hpp"
7
+
8
+ namespace jspp {
9
+
10
+ inline PromiseState::PromiseState() : result(std::make_shared<AnyValue>(AnyValue::make_undefined())) {}
11
+
12
+ inline JsPromise::JsPromise() : state(std::make_shared<PromiseState>()) {}
13
+
14
+ inline void JsPromise::resolve(const AnyValue& value) {
15
+ if (state->status != PromiseStatus::Pending) return;
16
+
17
+ if (value.is_promise()) {
18
+ auto p = value.as_promise();
19
+ if (p->state == state) {
20
+ reject(AnyValue::make_string("TypeError: Chaining cycle detected for promise"));
21
+ return;
22
+ }
23
+
24
+ auto weak_state = std::weak_ptr<PromiseState>(state);
25
+
26
+ p->then(
27
+ [weak_state](const AnyValue& v) {
28
+ if (auto s = weak_state.lock()) {
29
+ JsPromise localP; localP.state = s;
30
+ localP.resolve(v);
31
+ }
32
+ },
33
+ [weak_state](const AnyValue& r) {
34
+ if (auto s = weak_state.lock()) {
35
+ JsPromise localP; localP.state = s;
36
+ localP.reject(r);
37
+ }
38
+ }
39
+ );
40
+ return;
41
+ }
42
+
43
+ state->status = PromiseStatus::Fulfilled;
44
+ *(state->result) = value;
45
+
46
+ // Schedule callbacks
47
+ auto callbacks = state->onFulfilled;
48
+ state->onFulfilled.clear();
49
+ state->onRejected.clear();
50
+
51
+ for (auto& cb : callbacks) {
52
+ jspp::Scheduler::instance().enqueue([cb, value]() {
53
+ cb(value);
54
+ });
55
+ }
56
+ }
57
+
58
+ inline void JsPromise::reject(const AnyValue& reason) {
59
+ if (state->status != PromiseStatus::Pending) return;
60
+ state->status = PromiseStatus::Rejected;
61
+ *(state->result) = reason;
62
+
63
+ auto callbacks = state->onRejected;
64
+ state->onFulfilled.clear();
65
+ state->onRejected.clear();
66
+
67
+ for (auto& cb : callbacks) {
68
+ jspp::Scheduler::instance().enqueue([cb, reason]() {
69
+ cb(reason);
70
+ });
71
+ }
72
+ }
73
+
74
+ inline void JsPromise::then(std::function<void(const AnyValue&)> onFulfilled, std::function<void(const AnyValue&)> onRejected) {
75
+ if (state->status == PromiseStatus::Fulfilled) {
76
+ if (onFulfilled) {
77
+ AnyValue val = *(state->result);
78
+ jspp::Scheduler::instance().enqueue([onFulfilled, val]() {
79
+ onFulfilled(val);
80
+ });
81
+ }
82
+ } else if (state->status == PromiseStatus::Rejected) {
83
+ if (onRejected) {
84
+ AnyValue val = *(state->result);
85
+ jspp::Scheduler::instance().enqueue([onRejected, val]() {
86
+ onRejected(val);
87
+ });
88
+ }
89
+ } else {
90
+ if (onFulfilled) state->onFulfilled.push_back(onFulfilled);
91
+ if (onRejected) state->onRejected.push_back(onRejected);
92
+ }
93
+ }
94
+
95
+ inline std::string JsPromise::to_std_string() const {
96
+ return "[object Promise]";
97
+ }
98
+
99
+ inline AnyValue JsPromise::get_property(const std::string& key, const AnyValue& thisVal) {
100
+ // Prototype lookup
101
+ auto proto_it = PromisePrototypes::get(key, const_cast<JsPromise*>(this));
102
+ if (proto_it.has_value()) {
103
+ return AnyValue::resolve_property_for_read(proto_it.value(), thisVal, key);
104
+ }
105
+
106
+ auto it = props.find(key);
107
+ if (it != props.end()) {
108
+ return AnyValue::resolve_property_for_read(it->second, thisVal, key);
109
+ }
110
+ return AnyValue::make_undefined();
111
+ }
112
+
113
+ inline AnyValue JsPromise::set_property(const std::string& key, const AnyValue& value, const AnyValue& thisVal) {
114
+ // Prototype check (if we had setters on prototype)
115
+
116
+ auto it = props.find(key);
117
+ if (it != props.end()) {
118
+ return AnyValue::resolve_property_for_write(it->second, thisVal, value, key);
119
+ } else {
120
+ props[key] = value;
121
+ return value;
122
+ }
123
+ }
124
+
125
+ // --- Coroutine Methods ---
126
+
127
+ inline void JsPromisePromiseType::return_value(const AnyValue& val) {
128
+ promise.resolve(val);
129
+ }
130
+
131
+ inline void JsPromisePromiseType::unhandled_exception() {
132
+ try {
133
+ throw;
134
+ } catch (const Exception& e) {
135
+ promise.reject(*(e.data));
136
+ } catch (const std::exception& e) {
137
+ promise.reject(AnyValue::make_string(e.what()));
138
+ } catch (...) {
139
+ promise.reject(AnyValue::make_string("Unknown exception"));
140
+ }
141
+ }
142
+
143
+ inline auto JsPromisePromiseType::await_transform(const AnyValue& value) {
144
+ return AnyValueAwaiter{value};
145
+ }
146
+
147
+ // --- AnyValueAwaiter ---
148
+
149
+ inline bool AnyValueAwaiter::await_ready() {
150
+ if (!value.is_promise()) return true; // Non-promise values are ready immediately (for now)
151
+ // Always suspend for promises to ensure microtask interleaving, even if already resolved.
152
+ return false;
153
+ }
154
+
155
+ inline void AnyValueAwaiter::await_suspend(std::coroutine_handle<> h) {
156
+ if (!value.is_promise()) {
157
+ h.resume();
158
+ return;
159
+ }
160
+ auto p = value.as_promise();
161
+
162
+ // Attach resume to promise resolution.
163
+ // Since we are using the Scheduler in .then(), this will be queued.
164
+ p->then(
165
+ [h](AnyValue v) mutable { h.resume(); },
166
+ [h](AnyValue e) mutable { h.resume(); }
167
+ );
168
+ }
169
+
170
+ inline AnyValue AnyValueAwaiter::await_resume() {
171
+ if (!value.is_promise()) return value;
172
+ auto p = value.as_promise();
173
+ if (p->state->status == PromiseStatus::Fulfilled) {
174
+ return *(p->state->result);
175
+ } else {
176
+ // Throw exception to be caught by try/catch in coroutine
177
+ throw Exception(*(p->state->result));
178
+ }
179
+ }
180
+
181
+ }
@@ -3,7 +3,7 @@
3
3
  #include "types.hpp"
4
4
  #include "values/array.hpp"
5
5
  #include "values/string.hpp"
6
- #include "error.hpp"
6
+ #include "exception.hpp"
7
7
  #include "any_value.hpp"
8
8
  #include "values/prototypes/string.hpp"
9
9
 
@@ -22,13 +22,13 @@ jspp::JsIterator<jspp::AnyValue> jspp::JsString::get_iterator()
22
22
  co_return AnyValue::make_undefined();
23
23
  }
24
24
 
25
- jspp::AnyValue jspp::JsString::get_property(const std::string &key)
25
+ jspp::AnyValue jspp::JsString::get_property(const std::string &key, const AnyValue &thisVal)
26
26
  {
27
27
  // Check for prototype methods
28
28
  auto proto_fn = StringPrototypes::get(key, this);
29
29
  if (proto_fn.has_value())
30
30
  {
31
- return AnyValue::resolve_property_for_read(proto_fn.value());
31
+ return AnyValue::resolve_property_for_read(proto_fn.value(), thisVal, key);
32
32
  }
33
33
  // Handle character access by string index (e.g., "abc"["1"])
34
34
  if (JsArray::is_array_index(key))
@@ -10,13 +10,13 @@ std::string jspp::JsSymbol::to_std_string() const
10
10
  return "Symbol(" + description + ")";
11
11
  }
12
12
 
13
- jspp::AnyValue jspp::JsSymbol::get_property(const std::string &key)
13
+ jspp::AnyValue jspp::JsSymbol::get_property(const std::string &key, const AnyValue &thisVal)
14
14
  {
15
15
  // check prototype
16
16
  auto proto_it = SymbolPrototypes::get(key, this);
17
17
  if (proto_it.has_value())
18
18
  {
19
- return AnyValue::resolve_property_for_read(proto_it.value());
19
+ return AnyValue::resolve_property_for_read(proto_it.value(), thisVal, key);
20
20
  }
21
21
  // not found
22
22
  return AnyValue::make_undefined();
@@ -25,6 +25,7 @@ namespace jspp
25
25
  {
26
26
  std::optional<T> current_value;
27
27
  std::exception_ptr exception_;
28
+ T input_value;
28
29
 
29
30
  JsIterator get_return_object()
30
31
  {
@@ -40,10 +41,17 @@ namespace jspp
40
41
 
41
42
  // Handle co_yield
42
43
  template <typename From>
43
- std::suspend_always yield_value(From &&from)
44
+ auto yield_value(From &&from)
44
45
  {
45
46
  current_value = std::forward<From>(from);
46
- return {};
47
+ struct Awaiter
48
+ {
49
+ promise_type &p;
50
+ bool await_ready() { return false; }
51
+ void await_suspend(std::coroutine_handle<promise_type>) {}
52
+ T await_resume() { return p.input_value; }
53
+ };
54
+ return Awaiter{*this};
47
55
  }
48
56
 
49
57
  // Handle co_return
@@ -80,9 +88,9 @@ namespace jspp
80
88
  std::unordered_map<std::string, AnyValue> props;
81
89
 
82
90
  std::string to_std_string() const;
83
- NextResult next();
84
- std::vector<std::optional<T>> to_vector();
85
- AnyValue get_property(const std::string &key);
86
- AnyValue set_property(const std::string &key, const AnyValue &value);
91
+ NextResult next(const T &val = T());
92
+ std::vector<T> to_vector();
93
+ AnyValue get_property(const std::string &key, const AnyValue &thisVal);
94
+ AnyValue set_property(const std::string &key, const AnyValue &value, const AnyValue &thisVal);
87
95
  };
88
96
  }
@@ -1,6 +1,9 @@
1
1
  #pragma once
2
2
 
3
3
  #include "types.hpp"
4
+ #include "shape.hpp"
5
+ #include <vector>
6
+ #include <unordered_set>
4
7
 
5
8
  namespace jspp
6
9
  {
@@ -9,10 +12,18 @@ namespace jspp
9
12
 
10
13
  struct JsObject
11
14
  {
12
- std::map<std::string, AnyValue> props;
15
+ std::shared_ptr<Shape> shape;
16
+ std::vector<AnyValue> storage;
17
+ std::shared_ptr<AnyValue> proto;
18
+ std::unordered_set<std::string> deleted_keys;
19
+
20
+ JsObject();
21
+ JsObject(std::initializer_list<std::pair<std::string, AnyValue>> p, std::shared_ptr<AnyValue> pr = nullptr);
22
+ JsObject(const std::map<std::string, AnyValue> &p, std::shared_ptr<AnyValue> pr = nullptr);
13
23
 
14
24
  std::string to_std_string() const;
15
- AnyValue get_property(const std::string &key);
16
- AnyValue set_property(const std::string &key, const AnyValue &value);
25
+ bool has_property(const std::string &key) const;
26
+ AnyValue get_property(const std::string &key, const AnyValue &thisVal);
27
+ AnyValue set_property(const std::string &key, const AnyValue &value, const AnyValue &thisVal);
17
28
  };
18
29
  }
@@ -0,0 +1,73 @@
1
+ #pragma once
2
+
3
+ #include "types.hpp"
4
+ #include <vector>
5
+ #include <functional>
6
+ #include <memory>
7
+ #include <variant>
8
+ #include <coroutine>
9
+ #include <unordered_map>
10
+ #include <string>
11
+
12
+ namespace jspp
13
+ {
14
+ // Forward declaration of AnyValue
15
+ class AnyValue;
16
+
17
+ enum class PromiseStatus { Pending, Fulfilled, Rejected };
18
+
19
+ struct PromiseState
20
+ {
21
+ PromiseStatus status = PromiseStatus::Pending;
22
+ std::shared_ptr<AnyValue> result; // Value if fulfilled, reason if rejected
23
+ std::vector<std::function<void(const AnyValue&)>> onFulfilled;
24
+ std::vector<std::function<void(const AnyValue&)>> onRejected;
25
+
26
+ PromiseState(); // Defined in helpers
27
+ };
28
+
29
+ struct JsPromisePromiseType; // Forward declaration
30
+
31
+ struct JsPromise
32
+ {
33
+ using promise_type = JsPromisePromiseType;
34
+
35
+ std::shared_ptr<PromiseState> state;
36
+ std::unordered_map<std::string, AnyValue> props;
37
+
38
+ JsPromise();
39
+
40
+ // --- Promise Logic ---
41
+ void resolve(const AnyValue& value);
42
+ void reject(const AnyValue& reason);
43
+ void then(std::function<void(const AnyValue&)> onFulfilled, std::function<void(const AnyValue&)> onRejected = nullptr);
44
+
45
+ // --- Methods ---
46
+ std::string to_std_string() const;
47
+ AnyValue get_property(const std::string& key, const AnyValue& thisVal);
48
+ AnyValue set_property(const std::string& key, const AnyValue& value, const AnyValue& thisVal);
49
+ };
50
+
51
+ struct JsPromisePromiseType {
52
+ JsPromise promise;
53
+
54
+ JsPromise get_return_object() { return promise; }
55
+ std::suspend_never initial_suspend() { return {}; }
56
+ std::suspend_never final_suspend() noexcept { return {}; }
57
+
58
+ void return_value(const AnyValue& val);
59
+
60
+ void unhandled_exception();
61
+
62
+ // await_transform for AnyValue
63
+ auto await_transform(const AnyValue& value);
64
+ };
65
+
66
+ // Awaiter for AnyValue
67
+ struct AnyValueAwaiter {
68
+ const AnyValue& value; // Reference to the value being awaited
69
+ bool await_ready();
70
+ void await_suspend(std::coroutine_handle<> h);
71
+ AnyValue await_resume();
72
+ };
73
+ }