@ugo-studio/jspp 0.1.0

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 (42) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +162 -0
  3. package/dist/analysis/scope.js +77 -0
  4. package/dist/analysis/typeAnalyzer.js +224 -0
  5. package/dist/ast/types.js +1 -0
  6. package/dist/cli.js +63 -0
  7. package/dist/core/codegen/declaration-handlers.js +49 -0
  8. package/dist/core/codegen/expression-handlers.js +333 -0
  9. package/dist/core/codegen/function-handlers.js +94 -0
  10. package/dist/core/codegen/helpers.js +83 -0
  11. package/dist/core/codegen/index.js +54 -0
  12. package/dist/core/codegen/literal-handlers.js +32 -0
  13. package/dist/core/codegen/statement-handlers.js +485 -0
  14. package/dist/core/codegen/visitor.js +86 -0
  15. package/dist/core/parser.js +6 -0
  16. package/dist/core/traverser.js +19 -0
  17. package/dist/index.js +16 -0
  18. package/package.json +41 -0
  19. package/src/prelude/access.hpp +86 -0
  20. package/src/prelude/any_value.hpp +734 -0
  21. package/src/prelude/descriptors.hpp +25 -0
  22. package/src/prelude/error.hpp +31 -0
  23. package/src/prelude/error_helpers.hpp +59 -0
  24. package/src/prelude/index.hpp +29 -0
  25. package/src/prelude/library/console.hpp +111 -0
  26. package/src/prelude/library/global.hpp +10 -0
  27. package/src/prelude/library/symbol.hpp +8 -0
  28. package/src/prelude/log_string.hpp +403 -0
  29. package/src/prelude/operators.hpp +256 -0
  30. package/src/prelude/types.hpp +50 -0
  31. package/src/prelude/values/array.hpp +50 -0
  32. package/src/prelude/values/function.hpp +19 -0
  33. package/src/prelude/values/non_values.hpp +20 -0
  34. package/src/prelude/values/object.hpp +17 -0
  35. package/src/prelude/values/operators/array.hpp +165 -0
  36. package/src/prelude/values/operators/function.hpp +34 -0
  37. package/src/prelude/values/operators/object.hpp +34 -0
  38. package/src/prelude/values/prototypes/array.hpp +228 -0
  39. package/src/prelude/values/prototypes/function.hpp +0 -0
  40. package/src/prelude/values/prototypes/object.hpp +0 -0
  41. package/src/prelude/values/prototypes/string.hpp +357 -0
  42. package/src/prelude/well_known_symbols.hpp +10 -0
@@ -0,0 +1,256 @@
1
+ #pragma once
2
+
3
+ #include "types.hpp"
4
+ #include "any_value.hpp"
5
+ #include <cstdint> // For int32_t
6
+ #include <cmath> // For fmod, isnan, isinf, floor, abs, pow
7
+
8
+ namespace jspp
9
+ {
10
+ // Private namespace for helper functions that implement JS type conversions.
11
+ namespace Operators_Private
12
+ {
13
+ // Implements the ToNumber abstract operation from ECMA-262.
14
+ inline double ToNumber(const AnyValue &val)
15
+ {
16
+ if (val.is_number())
17
+ return val.as_double();
18
+ if (val.is_null())
19
+ return 0.0;
20
+ if (val.is_undefined() || val.is_uninitialized())
21
+ return std::numeric_limits<double>::quiet_NaN();
22
+ if (val.is_boolean())
23
+ return val.as_boolean() ? 1.0 : 0.0;
24
+ if (val.is_string())
25
+ {
26
+ const std::string &s = *val.as_string();
27
+ // JS considers empty or whitespace-only strings as 0.
28
+ if (s.empty() || std::all_of(s.begin(), s.end(), isspace))
29
+ return 0.0;
30
+ try
31
+ {
32
+ size_t pos;
33
+ double num = std::stod(s, &pos);
34
+ // Ensure the entire string was parsed, allowing for trailing whitespace.
35
+ while (pos < s.length() && std::isspace(s[pos]))
36
+ pos++;
37
+ if (pos != s.length())
38
+ return std::numeric_limits<double>::quiet_NaN();
39
+ return num;
40
+ }
41
+ catch (...)
42
+ {
43
+ return std::numeric_limits<double>::quiet_NaN();
44
+ }
45
+ }
46
+ // In a full engine, objects would be converted via valueOf/toString.
47
+ // Here we simplify and return NaN.
48
+ return std::numeric_limits<double>::quiet_NaN();
49
+ }
50
+ // Implements the ToInt32 abstract operation from ECMA-262.
51
+ inline int32_t ToInt32(const AnyValue &val)
52
+ {
53
+ double num = ToNumber(val);
54
+
55
+ if (std::isnan(num) || std::isinf(num) || num == 0)
56
+ return 0;
57
+
58
+ double posInt = std::signbit(num) ? -std::floor(std::abs(num)) : std::floor(std::abs(num));
59
+ double int32bit = fmod(posInt, 4294967296.0); // 2^32
60
+
61
+ if (int32bit >= 2147483648.0) // 2^31
62
+ return static_cast<int32_t>(int32bit - 4294967296.0);
63
+ else
64
+ return static_cast<int32_t>(int32bit);
65
+ }
66
+ }
67
+
68
+ // --- BASIC ARITHEMETIC
69
+ inline AnyValue operator+(const AnyValue &lhs, const AnyValue &rhs)
70
+ {
71
+ // Special case for addition: string concatenation has priority
72
+ if (lhs.is_string() || rhs.is_string())
73
+ return AnyValue::make_string(lhs.to_std_string() + rhs.to_std_string());
74
+ if (lhs.is_number() && rhs.is_number())
75
+ return AnyValue::make_number(lhs.as_double() + rhs.as_double());
76
+ // Fallback to numeric conversion
77
+ return AnyValue::make_number(Operators_Private::ToNumber(lhs) + Operators_Private::ToNumber(rhs));
78
+ }
79
+ inline AnyValue operator-(const AnyValue &lhs, const AnyValue &rhs)
80
+ {
81
+ return AnyValue::make_number(Operators_Private::ToNumber(lhs) - Operators_Private::ToNumber(rhs));
82
+ }
83
+ inline AnyValue operator*(const AnyValue &lhs, const AnyValue &rhs)
84
+ {
85
+ return AnyValue::make_number(Operators_Private::ToNumber(lhs) * Operators_Private::ToNumber(rhs));
86
+ }
87
+ inline AnyValue operator/(const AnyValue &lhs, const AnyValue &rhs)
88
+ {
89
+ return AnyValue::make_number(Operators_Private::ToNumber(lhs) / Operators_Private::ToNumber(rhs));
90
+ }
91
+ inline AnyValue operator%(const AnyValue &lhs, const AnyValue &rhs)
92
+ {
93
+ return AnyValue::make_number(std::fmod(Operators_Private::ToNumber(lhs), Operators_Private::ToNumber(rhs)));
94
+ }
95
+
96
+ // --- UNARY OPERATORS
97
+ inline AnyValue operator-(const AnyValue &val)
98
+ {
99
+ return AnyValue::make_number(-Operators_Private::ToNumber(val));
100
+ }
101
+ inline AnyValue operator~(const AnyValue &val)
102
+ {
103
+ return AnyValue::make_number(~Operators_Private::ToInt32(val));
104
+ }
105
+
106
+ // --- EXPONENTIATION
107
+ inline AnyValue pow(const AnyValue &lhs, const AnyValue &rhs)
108
+ {
109
+ double base = Operators_Private::ToNumber(lhs);
110
+ double exp = Operators_Private::ToNumber(rhs);
111
+ return AnyValue::make_number(std::pow(base, exp));
112
+ }
113
+
114
+ // --- COMPARISON OPERATORS
115
+ inline AnyValue operator<(const AnyValue &lhs, const AnyValue &rhs)
116
+ {
117
+ // Simplified Abstract Relational Comparison
118
+ if (lhs.is_string() && rhs.is_string())
119
+ return AnyValue::make_boolean(*lhs.as_string() < *rhs.as_string());
120
+
121
+ double l = Operators_Private::ToNumber(lhs);
122
+ double r = Operators_Private::ToNumber(rhs);
123
+
124
+ if (std::isnan(l) || std::isnan(r))
125
+ return AnyValue::make_boolean(false); // Comparison with NaN is false
126
+
127
+ return AnyValue::make_boolean(l < r);
128
+ }
129
+ inline AnyValue operator>(const AnyValue &lhs, const AnyValue &rhs)
130
+ {
131
+ return rhs < lhs;
132
+ }
133
+ inline AnyValue operator<=(const AnyValue &lhs, const AnyValue &rhs)
134
+ {
135
+ // a <= b is equivalent to !(b < a)
136
+ AnyValue result = rhs < lhs;
137
+ return AnyValue::make_boolean(!result.as_boolean());
138
+ }
139
+ inline AnyValue operator>=(const AnyValue &lhs, const AnyValue &rhs)
140
+ {
141
+ // a >= b is equivalent to !(a < b)
142
+ AnyValue result = lhs < rhs;
143
+ return AnyValue::make_boolean(!result.as_boolean());
144
+ }
145
+ inline AnyValue operator==(const AnyValue &lhs, const AnyValue &rhs)
146
+ {
147
+ return AnyValue::make_boolean(lhs.is_equal_to(rhs));
148
+ }
149
+ inline AnyValue operator!=(const AnyValue &lhs, const AnyValue &rhs)
150
+ {
151
+ return AnyValue::make_boolean(!lhs.is_equal_to(rhs));
152
+ }
153
+
154
+ // --- BITWISE OPERATORS
155
+ inline AnyValue operator^(const AnyValue &lhs, const AnyValue &rhs)
156
+ {
157
+ return AnyValue::make_number(Operators_Private::ToInt32(lhs) ^ Operators_Private::ToInt32(rhs));
158
+ }
159
+ inline AnyValue operator&(const AnyValue &lhs, const AnyValue &rhs)
160
+ {
161
+ return AnyValue::make_number(Operators_Private::ToInt32(lhs) & Operators_Private::ToInt32(rhs));
162
+ }
163
+ inline AnyValue operator|(const AnyValue &lhs, const AnyValue &rhs)
164
+ {
165
+ return AnyValue::make_number(Operators_Private::ToInt32(lhs) | Operators_Private::ToInt32(rhs));
166
+ }
167
+
168
+ // --- SHIFT OPERATORS
169
+ inline AnyValue operator<<(const AnyValue &lhs, const AnyValue &rhs)
170
+ {
171
+ // The right operand is treated as an unsigned 32-bit integer, and only the lower 5 bits are used.
172
+ return AnyValue::make_number(Operators_Private::ToInt32(lhs) << (Operators_Private::ToInt32(rhs) & 0x1F));
173
+ }
174
+ inline AnyValue operator>>(const AnyValue &lhs, const AnyValue &rhs)
175
+ {
176
+ return AnyValue::make_number(Operators_Private::ToInt32(lhs) >> (Operators_Private::ToInt32(rhs) & 0x1F));
177
+ }
178
+
179
+ // --- INCREMENT / DECREMENT
180
+ inline AnyValue &operator++(AnyValue &val) // pre-increment
181
+ {
182
+ double num = Operators_Private::ToNumber(val);
183
+ val = AnyValue::make_number(num + 1.0);
184
+ return val;
185
+ }
186
+ inline AnyValue operator++(AnyValue &val, int) // post-increment
187
+ {
188
+ AnyValue old = AnyValue::make_number(Operators_Private::ToNumber(val));
189
+ ++val;
190
+ return old;
191
+ }
192
+ inline AnyValue &operator--(AnyValue &val) // pre-decrement
193
+ {
194
+ double num = Operators_Private::ToNumber(val);
195
+ val = AnyValue::make_number(num - 1.0);
196
+ return val;
197
+ }
198
+ inline AnyValue operator--(AnyValue &val, int) // post-decrement
199
+ {
200
+ AnyValue old = AnyValue::make_number(Operators_Private::ToNumber(val));
201
+ --val;
202
+ return old;
203
+ }
204
+
205
+ // --- COMPOUND ASSIGNMENT
206
+ inline AnyValue &operator+=(AnyValue &lhs, const AnyValue &rhs)
207
+ {
208
+ lhs = lhs + rhs;
209
+ return lhs;
210
+ }
211
+ inline AnyValue &operator-=(AnyValue &lhs, const AnyValue &rhs)
212
+ {
213
+ lhs = lhs - rhs;
214
+ return lhs;
215
+ }
216
+ inline AnyValue &operator*=(AnyValue &lhs, const AnyValue &rhs)
217
+ {
218
+ lhs = lhs * rhs;
219
+ return lhs;
220
+ }
221
+ inline AnyValue &operator/=(AnyValue &lhs, const AnyValue &rhs)
222
+ {
223
+ lhs = lhs / rhs;
224
+ return lhs;
225
+ }
226
+ inline AnyValue &operator%=(AnyValue &lhs, const AnyValue &rhs)
227
+ {
228
+ lhs = lhs % rhs;
229
+ return lhs;
230
+ }
231
+ inline AnyValue &operator^=(AnyValue &lhs, const AnyValue &rhs)
232
+ {
233
+ lhs = lhs ^ rhs;
234
+ return lhs;
235
+ }
236
+ inline AnyValue &operator&=(AnyValue &lhs, const AnyValue &rhs)
237
+ {
238
+ lhs = lhs & rhs;
239
+ return lhs;
240
+ }
241
+ inline AnyValue &operator|=(AnyValue &lhs, const AnyValue &rhs)
242
+ {
243
+ lhs = lhs | rhs;
244
+ return lhs;
245
+ }
246
+ inline AnyValue &operator<<=(AnyValue &lhs, const AnyValue &rhs)
247
+ {
248
+ lhs = lhs << rhs;
249
+ return lhs;
250
+ }
251
+ inline AnyValue &operator>>=(AnyValue &lhs, const AnyValue &rhs)
252
+ {
253
+ lhs = lhs >> rhs;
254
+ return lhs;
255
+ }
256
+ }
@@ -0,0 +1,50 @@
1
+ #pragma once
2
+
3
+ #include <iostream>
4
+ #include <string>
5
+ #include <vector>
6
+ #include <variant>
7
+ #include <functional>
8
+ #include <memory>
9
+ #include <unordered_map>
10
+ #include <algorithm>
11
+ #include <cctype>
12
+ #include <cstring>
13
+ #include <set>
14
+ #include <cmath>
15
+ #include <optional>
16
+
17
+ // JSPP standard library
18
+ namespace jspp
19
+ {
20
+ // Forward declarations
21
+ struct JsUndefined; // cannot set property
22
+ struct JsNull; // cannot set property
23
+ struct JsUninitialized; // cannot set property
24
+ struct JsObject; // can set property
25
+ struct JsArray; // can set property
26
+ struct JsFunction; // can set property
27
+
28
+ // Object property configuration forward declarations
29
+ struct DataDescriptor;
30
+ struct AccessorDescriptor;
31
+
32
+ // Dynamic AnyValue
33
+ class AnyValue;
34
+
35
+ // Custom runtime exception
36
+ struct RuntimeError;
37
+
38
+ // Arithemetic operators
39
+ inline AnyValue pow(const AnyValue &lhs, const AnyValue &rhs);
40
+
41
+ // AnyValue prototypes
42
+ namespace StringPrototypes
43
+ {
44
+ inline std::optional<AnyValue> get(const std::string &key, const std::unique_ptr<std::string> &self);
45
+ }
46
+ namespace ArrayPrototypes
47
+ {
48
+ inline std::optional<AnyValue> get(const std::string &key, JsArray *self);
49
+ }
50
+ }
@@ -0,0 +1,50 @@
1
+ #pragma once
2
+
3
+ #include "types.hpp"
4
+ #include <optional>
5
+
6
+ namespace jspp
7
+ {
8
+ class AnyValue;
9
+
10
+ struct JsArray
11
+ {
12
+ std::vector<std::optional<AnyValue>> dense; // dense storage for small/contiguous indices
13
+ std::unordered_map<uint32_t, std::optional<AnyValue>> sparse; // sparse indices (very large indices)
14
+ std::unordered_map<std::string, AnyValue> props; // non-index string properties
15
+ uint64_t length = 0;
16
+
17
+ JsArray() = default;
18
+ explicit JsArray(const std::vector<std::optional<AnyValue>> &items) : dense(items), length(items.size()) {}
19
+
20
+ std::string to_std_string() const;
21
+
22
+ AnyValue get_property(const std::string &key);
23
+ AnyValue get_property(uint32_t idx);
24
+ AnyValue set_property(const std::string &key, const AnyValue &value);
25
+ AnyValue set_property(uint32_t idx, const AnyValue &value);
26
+
27
+ static bool is_array_index(const std::string &s)
28
+ {
29
+ if (s.empty())
30
+ return false;
31
+ // must be all digits
32
+ for (char c : s)
33
+ if (!std::isdigit(static_cast<unsigned char>(c)))
34
+ return false;
35
+ // reject the special 2^32-1 string
36
+ if (s == "4294967295")
37
+ return false;
38
+ // parse without overflow up to 2^32-1
39
+ uint64_t v = 0;
40
+ for (char c : s)
41
+ {
42
+ v = v * 10 + (c - '0');
43
+ if (v >= (1ULL << 32))
44
+ return false;
45
+ }
46
+ // ToString(ToUint32(v)) === s?
47
+ return std::to_string(static_cast<uint32_t>(v)) == s;
48
+ }
49
+ };
50
+ }
@@ -0,0 +1,19 @@
1
+ #pragma once
2
+
3
+ #include "types.hpp"
4
+
5
+ namespace jspp
6
+ {
7
+ class AnyValue;
8
+
9
+ struct JsFunction
10
+ {
11
+ std::function<AnyValue(const std::vector<AnyValue> &)> call;
12
+ std::string name;
13
+ std::unordered_map<std::string, AnyValue> props;
14
+
15
+ std::string to_std_string() const;
16
+ AnyValue get_property(const std::string &key);
17
+ AnyValue set_property(const std::string &key, const AnyValue &value);
18
+ };
19
+ }
@@ -0,0 +1,20 @@
1
+ #pragma once
2
+
3
+ #include "types.hpp"
4
+
5
+ namespace jspp
6
+ {
7
+
8
+ struct JsUndefined
9
+ {
10
+ };
11
+
12
+ struct JsNull
13
+ {
14
+ };
15
+
16
+ struct JsUninitialized
17
+ {
18
+ };
19
+
20
+ }
@@ -0,0 +1,17 @@
1
+ #pragma once
2
+
3
+ #include "types.hpp"
4
+
5
+ namespace jspp
6
+ {
7
+ class AnyValue;
8
+
9
+ struct JsObject
10
+ {
11
+ std::unordered_map<std::string, AnyValue> props;
12
+
13
+ std::string to_std_string() const;
14
+ AnyValue get_property(const std::string &key);
15
+ AnyValue set_property(const std::string &key, const AnyValue &value);
16
+ };
17
+ }
@@ -0,0 +1,165 @@
1
+ #pragma once
2
+
3
+ #include "types.hpp"
4
+ #include "values/array.hpp"
5
+ #include "error.hpp"
6
+ #include "any_value.hpp"
7
+ #include "values/prototypes/array.hpp"
8
+
9
+ std::string jspp::JsArray::to_std_string() const
10
+ {
11
+ if (length == 0)
12
+ {
13
+ return "";
14
+ }
15
+
16
+ std::string result = "";
17
+ for (uint64_t i = 0; i < length; ++i)
18
+ {
19
+ std::optional<AnyValue> itemVal;
20
+ if (i < dense.size())
21
+ {
22
+ itemVal = dense[i];
23
+ }
24
+ else
25
+ {
26
+ auto it = sparse.find(static_cast<uint32_t>(i));
27
+ if (it != sparse.end())
28
+ {
29
+ itemVal = it->second;
30
+ }
31
+ }
32
+
33
+ if (itemVal.has_value())
34
+ {
35
+ const auto &item = itemVal.value();
36
+ if (!item.is_undefined() && !item.is_null())
37
+ {
38
+ result += item.to_std_string();
39
+ }
40
+ }
41
+
42
+ if (i < length - 1)
43
+ {
44
+ result += ",";
45
+ }
46
+ }
47
+ return result;
48
+ }
49
+
50
+ jspp::AnyValue jspp::JsArray::get_property(const std::string &key)
51
+ {
52
+ if (
53
+ !key.empty() && std::isdigit(static_cast<unsigned char>(key[0])) // Quick check: if the first character is not a digit, it can't be a standard index.
54
+ && is_array_index(key))
55
+ {
56
+ uint32_t idx = static_cast<uint32_t>(std::stoull(key));
57
+ return get_property(idx);
58
+ }
59
+ else
60
+ {
61
+ auto it = props.find(key);
62
+ if (it == props.end())
63
+ {
64
+ // check prototype
65
+ auto proto_it = ArrayPrototypes::get(key, this);
66
+ if (proto_it.has_value())
67
+ {
68
+ return AnyValue::resolve_property_for_read(proto_it.value());
69
+ }
70
+ // not found
71
+ return AnyValue::make_undefined();
72
+ }
73
+ return AnyValue::resolve_property_for_read(it->second);
74
+ }
75
+ }
76
+
77
+ jspp::AnyValue jspp::JsArray::get_property(uint32_t idx)
78
+ {
79
+ if (idx < dense.size())
80
+ {
81
+ return AnyValue::resolve_property_for_read(dense[idx].value_or(AnyValue::make_undefined()));
82
+ }
83
+ const auto &it = sparse.find(idx);
84
+ if (it != sparse.end())
85
+ {
86
+ return AnyValue::resolve_property_for_read(it->second.value_or(AnyValue::make_undefined()));
87
+ }
88
+ return AnyValue::make_undefined();
89
+ }
90
+
91
+ jspp::AnyValue jspp::JsArray::set_property(const std::string &key, const AnyValue &value)
92
+ {
93
+ if (
94
+ !key.empty() && std::isdigit(static_cast<unsigned char>(key[0])) // Quick check: if the first character is not a digit, it can't be a standard index.
95
+ && is_array_index(key))
96
+ {
97
+ uint32_t idx = static_cast<uint32_t>(std::stoull(key));
98
+ return set_property(idx, value);
99
+ }
100
+ else
101
+ {
102
+ // set prototype property if accessor descriptor
103
+ auto proto_it = ArrayPrototypes::get(key, this);
104
+ if (proto_it.has_value())
105
+ {
106
+ auto proto_value = proto_it.value();
107
+ if (proto_value.is_accessor_descriptor())
108
+ {
109
+ return AnyValue::resolve_property_for_write(proto_it.value(), value);
110
+ }
111
+ }
112
+
113
+ // set own property
114
+ auto it = props.find(key);
115
+ if (it != props.end())
116
+ {
117
+ return AnyValue::resolve_property_for_write(it->second, value);
118
+ }
119
+ else
120
+ {
121
+ props[key] = value;
122
+ return value;
123
+ }
124
+ }
125
+ }
126
+
127
+ jspp::AnyValue jspp::JsArray::set_property(uint32_t idx, const AnyValue &value)
128
+ {
129
+ uint64_t newLen = static_cast<uint64_t>(idx) + 1;
130
+ if (newLen > length)
131
+ length = newLen;
132
+
133
+ const uint32_t DENSE_GROW_THRESHOLD = 1024;
134
+ if (idx < dense.size())
135
+ {
136
+ if (!dense[idx].has_value())
137
+ {
138
+ dense[idx] = AnyValue::make_undefined();
139
+ }
140
+ return AnyValue::resolve_property_for_write(dense[idx].value(), value);
141
+ }
142
+ else if (idx <= dense.size() + DENSE_GROW_THRESHOLD)
143
+ {
144
+ dense.resize(idx + 1);
145
+ dense[idx] = value;
146
+ return value;
147
+ }
148
+ else
149
+ {
150
+ auto it = sparse.find(idx);
151
+ if (it != sparse.end())
152
+ {
153
+ if (!it->second.has_value())
154
+ {
155
+ it->second = AnyValue::make_undefined();
156
+ }
157
+ return AnyValue::resolve_property_for_write(it->second.value(), value);
158
+ }
159
+ else
160
+ {
161
+ sparse[idx] = value;
162
+ return value;
163
+ }
164
+ }
165
+ }
@@ -0,0 +1,34 @@
1
+ #pragma once
2
+
3
+ #include "types.hpp"
4
+ #include "values/function.hpp"
5
+ #include "any_value.hpp"
6
+
7
+ std::string jspp::JsFunction::to_std_string() const
8
+ {
9
+ return "function " + name + "() { [native code] }";
10
+ }
11
+
12
+ jspp::AnyValue jspp::JsFunction::get_property(const std::string &key)
13
+ {
14
+ auto it = props.find(key);
15
+ if (it != props.end())
16
+ {
17
+ return jspp::AnyValue::resolve_property_for_read(it->second);
18
+ }
19
+ return jspp::AnyValue::make_undefined();
20
+ }
21
+
22
+ jspp::AnyValue jspp::JsFunction::set_property(const std::string &key, const AnyValue &value)
23
+ {
24
+ auto it = props.find(key);
25
+ if (it != props.end())
26
+ {
27
+ return jspp::AnyValue::resolve_property_for_write(it->second, value);
28
+ }
29
+ else
30
+ {
31
+ props[key] = value;
32
+ return value;
33
+ }
34
+ }
@@ -0,0 +1,34 @@
1
+ #pragma once
2
+
3
+ #include "types.hpp"
4
+ #include "values/object.hpp"
5
+ #include "any_value.hpp"
6
+
7
+ std::string jspp::JsObject::to_std_string() const
8
+ {
9
+ return "[Object Object]";
10
+ }
11
+
12
+ jspp::AnyValue jspp::JsObject::get_property(const std::string &key)
13
+ {
14
+ auto it = props.find(key);
15
+ if (it != props.end())
16
+ {
17
+ return jspp::AnyValue::resolve_property_for_read(it->second);
18
+ }
19
+ return jspp::AnyValue::make_undefined();
20
+ }
21
+
22
+ jspp::AnyValue jspp::JsObject::set_property(const std::string &key, const AnyValue &value)
23
+ {
24
+ auto it = props.find(key);
25
+ if (it != props.end())
26
+ {
27
+ return jspp::AnyValue::resolve_property_for_write(it->second, value);
28
+ }
29
+ else
30
+ {
31
+ props[key] = value;
32
+ return value;
33
+ }
34
+ }