@ugo-studio/jspp 0.1.2 → 0.1.4

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 (72) hide show
  1. package/README.md +5 -3
  2. package/dist/analysis/scope.js +38 -15
  3. package/dist/analysis/typeAnalyzer.js +257 -23
  4. package/dist/ast/types.js +6 -0
  5. package/dist/cli.js +3 -4
  6. package/dist/core/codegen/class-handlers.js +127 -0
  7. package/dist/core/codegen/control-flow-handlers.js +464 -0
  8. package/dist/core/codegen/declaration-handlers.js +31 -14
  9. package/dist/core/codegen/expression-handlers.js +432 -116
  10. package/dist/core/codegen/function-handlers.js +110 -13
  11. package/dist/core/codegen/helpers.js +76 -8
  12. package/dist/core/codegen/index.js +18 -5
  13. package/dist/core/codegen/literal-handlers.js +3 -0
  14. package/dist/core/codegen/statement-handlers.js +152 -186
  15. package/dist/core/codegen/visitor.js +35 -3
  16. package/package.json +3 -3
  17. package/src/prelude/any_value.hpp +658 -734
  18. package/src/prelude/any_value_access.hpp +103 -0
  19. package/src/prelude/any_value_defines.hpp +151 -0
  20. package/src/prelude/any_value_helpers.hpp +246 -0
  21. package/src/prelude/exception.hpp +31 -0
  22. package/src/prelude/exception_helpers.hpp +49 -0
  23. package/src/prelude/index.hpp +35 -12
  24. package/src/prelude/library/console.hpp +20 -20
  25. package/src/prelude/library/error.hpp +111 -0
  26. package/src/prelude/library/global.hpp +15 -4
  27. package/src/prelude/library/performance.hpp +25 -0
  28. package/src/prelude/library/promise.hpp +121 -0
  29. package/src/prelude/library/symbol.hpp +60 -4
  30. package/src/prelude/library/timer.hpp +92 -0
  31. package/src/prelude/scheduler.hpp +145 -0
  32. package/src/prelude/types.hpp +33 -6
  33. package/src/prelude/utils/access.hpp +174 -0
  34. package/src/prelude/utils/log_any_value/array.hpp +245 -0
  35. package/src/prelude/utils/log_any_value/config.hpp +32 -0
  36. package/src/prelude/utils/log_any_value/function.hpp +37 -0
  37. package/src/prelude/utils/log_any_value/fwd.hpp +15 -0
  38. package/src/prelude/utils/log_any_value/helpers.hpp +62 -0
  39. package/src/prelude/utils/log_any_value/log_any_value.hpp +94 -0
  40. package/src/prelude/utils/log_any_value/object.hpp +119 -0
  41. package/src/prelude/utils/log_any_value/primitives.hpp +41 -0
  42. package/src/prelude/{operators.hpp → utils/operators.hpp} +31 -12
  43. package/src/prelude/utils/well_known_symbols.hpp +13 -0
  44. package/src/prelude/values/array.hpp +5 -2
  45. package/src/prelude/{descriptors.hpp → values/descriptors.hpp} +2 -2
  46. package/src/prelude/values/function.hpp +76 -19
  47. package/src/prelude/values/{operators → helpers}/array.hpp +30 -14
  48. package/src/prelude/values/helpers/function.hpp +125 -0
  49. package/src/prelude/values/helpers/iterator.hpp +107 -0
  50. package/src/prelude/values/helpers/object.hpp +64 -0
  51. package/src/prelude/values/helpers/promise.hpp +181 -0
  52. package/src/prelude/values/helpers/string.hpp +50 -0
  53. package/src/prelude/values/helpers/symbol.hpp +23 -0
  54. package/src/prelude/values/iterator.hpp +96 -0
  55. package/src/prelude/values/object.hpp +8 -3
  56. package/src/prelude/values/promise.hpp +73 -0
  57. package/src/prelude/values/prototypes/array.hpp +23 -16
  58. package/src/prelude/values/prototypes/function.hpp +26 -0
  59. package/src/prelude/values/prototypes/iterator.hpp +58 -0
  60. package/src/prelude/values/prototypes/object.hpp +26 -0
  61. package/src/prelude/values/prototypes/promise.hpp +124 -0
  62. package/src/prelude/values/prototypes/string.hpp +366 -357
  63. package/src/prelude/values/prototypes/symbol.hpp +41 -0
  64. package/src/prelude/values/string.hpp +25 -0
  65. package/src/prelude/values/symbol.hpp +102 -0
  66. package/src/prelude/access.hpp +0 -86
  67. package/src/prelude/error.hpp +0 -31
  68. package/src/prelude/error_helpers.hpp +0 -59
  69. package/src/prelude/log_string.hpp +0 -403
  70. package/src/prelude/values/operators/function.hpp +0 -34
  71. package/src/prelude/values/operators/object.hpp +0 -34
  72. package/src/prelude/well_known_symbols.hpp +0 -10
@@ -0,0 +1,103 @@
1
+ #pragma once
2
+
3
+ #include "types.hpp"
4
+ #include "any_value.hpp"
5
+
6
+ jspp::AnyValue jspp::AnyValue::get_own_property(const std::string &key) const
7
+ {
8
+ return get_property_with_receiver(key, *this);
9
+ }
10
+ jspp::AnyValue jspp::AnyValue::get_own_property(uint32_t idx) const noexcept
11
+ {
12
+ switch (storage.type)
13
+ {
14
+ case JsType::Array:
15
+ return storage.array->get_property(idx);
16
+ case JsType::String:
17
+ return storage.str->get_property(idx);
18
+ default:
19
+ return get_own_property(std::to_string(idx));
20
+ }
21
+ }
22
+ jspp::AnyValue jspp::AnyValue::get_own_property(const AnyValue &key) const noexcept
23
+ {
24
+ if (key.storage.type == JsType::Number && storage.type == JsType::Array)
25
+ return storage.array->get_property(key.storage.number);
26
+ if (key.storage.type == JsType::Number && storage.type == JsType::String)
27
+ return storage.str->get_property(key.storage.number);
28
+
29
+ // If the key is a Symbol, use its internal key string
30
+ if (key.storage.type == JsType::Symbol)
31
+ return get_own_property(key.storage.symbol->key);
32
+
33
+ return get_own_property(key.to_std_string());
34
+ }
35
+
36
+ jspp::AnyValue jspp::AnyValue::get_property_with_receiver(const std::string &key, const AnyValue &receiver) const
37
+ {
38
+ switch (storage.type)
39
+ {
40
+ case JsType::Object:
41
+ return storage.object->get_property(key, receiver);
42
+ case JsType::Array:
43
+ return storage.array->get_property(key, receiver);
44
+ case JsType::Function:
45
+ return storage.function->get_property(key, receiver);
46
+ case JsType::Promise:
47
+ return storage.promise->get_property(key, receiver);
48
+ case JsType::Iterator:
49
+ return storage.iterator->get_property(key, receiver);
50
+ case JsType::Symbol:
51
+ return storage.symbol->get_property(key, receiver);
52
+ case JsType::String:
53
+ return storage.str->get_property(key, receiver);
54
+ case JsType::Undefined:
55
+ throw Exception::make_exception("Cannot read properties of undefined (reading '" + key + "')", "TypeError");
56
+ case JsType::Null:
57
+ throw Exception::make_exception("Cannot read properties of null (reading '" + key + "')", "TypeError");
58
+ default:
59
+ return AnyValue::make_undefined();
60
+ }
61
+ }
62
+
63
+ jspp::AnyValue jspp::AnyValue::set_own_property(const std::string &key, const AnyValue &value) const
64
+ {
65
+ switch (storage.type)
66
+ {
67
+ case JsType::Object:
68
+ return storage.object->set_property(key, value, *this);
69
+ case JsType::Array:
70
+ return storage.array->set_property(key, value, *this);
71
+ case JsType::Function:
72
+ return storage.function->set_property(key, value, *this);
73
+ case JsType::Promise:
74
+ return storage.promise->set_property(key, value, *this);
75
+ case JsType::Undefined:
76
+ throw Exception::make_exception("Cannot set properties of undefined (setting '" + key + "')", "TypeError");
77
+ case JsType::Null:
78
+ throw Exception::make_exception("Cannot set properties of null (setting '" + key + "')", "TypeError");
79
+ default:
80
+ return value;
81
+ }
82
+ }
83
+ jspp::AnyValue jspp::AnyValue::set_own_property(uint32_t idx, const AnyValue &value) const
84
+ {
85
+ if (storage.type == JsType::Array)
86
+ {
87
+ return storage.array->set_property(idx, value);
88
+ }
89
+ return set_own_property(std::to_string(idx), value);
90
+ }
91
+ jspp::AnyValue jspp::AnyValue::set_own_property(const AnyValue &key, const AnyValue &value) const
92
+ {
93
+ if (key.storage.type == JsType::Number && storage.type == JsType::Array)
94
+ {
95
+ return storage.array->set_property(key.storage.number, value);
96
+ }
97
+
98
+ // If the key is a Symbol, use its internal key string
99
+ if (key.storage.type == JsType::Symbol)
100
+ return set_own_property(key.storage.symbol->key, value);
101
+
102
+ return set_own_property(key.to_std_string(), value);
103
+ }
@@ -0,0 +1,151 @@
1
+ #pragma once
2
+
3
+ #include "types.hpp"
4
+ #include "any_value.hpp"
5
+ #include "values/object.hpp"
6
+ #include "values/function.hpp"
7
+
8
+ namespace jspp
9
+ {
10
+
11
+ inline void AnyValue::define_data_property(const std::string &key, const AnyValue &value)
12
+ {
13
+ if (is_object())
14
+ {
15
+ storage.object->props[key] = value;
16
+ }
17
+ else if (is_function())
18
+ {
19
+ storage.function->props[key] = value;
20
+ }
21
+ }
22
+
23
+ inline void AnyValue::define_data_property(const AnyValue &key, const AnyValue &value)
24
+ {
25
+ if (key.is_symbol())
26
+ define_data_property(key.as_symbol()->key, value);
27
+ else
28
+ define_data_property(key.to_std_string(), value);
29
+ }
30
+
31
+ inline void AnyValue::define_data_property(const std::string &key, const AnyValue &value, bool writable, bool enumerable, bool configurable)
32
+ {
33
+ define_data_property(key, AnyValue::make_data_descriptor(value, writable, enumerable, configurable));
34
+ }
35
+
36
+ inline void AnyValue::define_getter(const std::string &key, const AnyValue &getter)
37
+ {
38
+ if (is_object())
39
+ {
40
+ auto &props = storage.object->props;
41
+ auto it = props.find(key);
42
+ if (it != props.end() && it->second.is_accessor_descriptor())
43
+ {
44
+ auto desc = it->second.as_accessor_descriptor();
45
+ desc->get = [getter](const AnyValue &thisVal, const std::vector<AnyValue> &args) -> AnyValue
46
+ {
47
+ return getter.as_function()->call(thisVal, args);
48
+ };
49
+ }
50
+ else
51
+ {
52
+ auto getFunc = [getter](const AnyValue &thisVal, const std::vector<AnyValue> &args) -> AnyValue
53
+ {
54
+ return getter.as_function()->call(thisVal, args);
55
+ };
56
+ props[key] = AnyValue::make_accessor_descriptor(getFunc, std::nullopt, true, true);
57
+ }
58
+ }
59
+ else if (is_function())
60
+ {
61
+ auto &props = storage.function->props;
62
+ auto it = props.find(key);
63
+ if (it != props.end() && it->second.is_accessor_descriptor())
64
+ {
65
+ auto desc = it->second.as_accessor_descriptor();
66
+ desc->get = [getter](const AnyValue &thisVal, const std::vector<AnyValue> &args) -> AnyValue
67
+ {
68
+ return getter.as_function()->call(thisVal, args);
69
+ };
70
+ }
71
+ else
72
+ {
73
+ auto getFunc = [getter](const AnyValue &thisVal, const std::vector<AnyValue> &args) -> AnyValue
74
+ {
75
+ return getter.as_function()->call(thisVal, args);
76
+ };
77
+ props[key] = AnyValue::make_accessor_descriptor(getFunc, std::nullopt, true, true);
78
+ }
79
+ }
80
+ }
81
+
82
+ inline void AnyValue::define_getter(const AnyValue &key, const AnyValue &getter)
83
+ {
84
+ if (key.is_symbol())
85
+ define_getter(key.as_symbol()->key, getter);
86
+ else
87
+ define_getter(key.to_std_string(), getter);
88
+ }
89
+
90
+ inline void AnyValue::define_setter(const std::string &key, const AnyValue &setter)
91
+ {
92
+ if (is_object())
93
+ {
94
+ auto &props = storage.object->props;
95
+ auto it = props.find(key);
96
+ if (it != props.end() && it->second.is_accessor_descriptor())
97
+ {
98
+ auto desc = it->second.as_accessor_descriptor();
99
+ desc->set = [setter](const AnyValue &thisVal, const std::vector<AnyValue> &args) -> AnyValue
100
+ {
101
+ if (args.empty())
102
+ return AnyValue::make_undefined();
103
+ return setter.as_function()->call(thisVal, args);
104
+ };
105
+ }
106
+ else
107
+ {
108
+ auto setFunc = [setter](const AnyValue &thisVal, const std::vector<AnyValue> &args) -> AnyValue
109
+ {
110
+ if (args.empty())
111
+ return AnyValue::make_undefined();
112
+ return setter.as_function()->call(thisVal, args);
113
+ };
114
+ props[key] = AnyValue::make_accessor_descriptor(std::nullopt, setFunc, true, true);
115
+ }
116
+ }
117
+ else if (is_function())
118
+ {
119
+ auto &props = storage.function->props;
120
+ auto it = props.find(key);
121
+ if (it != props.end() && it->second.is_accessor_descriptor())
122
+ {
123
+ auto desc = it->second.as_accessor_descriptor();
124
+ desc->set = [setter](const AnyValue &thisVal, const std::vector<AnyValue> &args) -> AnyValue
125
+ {
126
+ if (args.empty())
127
+ return AnyValue::make_undefined();
128
+ return setter.as_function()->call(thisVal, args);
129
+ };
130
+ }
131
+ else
132
+ {
133
+ auto setFunc = [setter](const AnyValue &thisVal, const std::vector<AnyValue> &args) -> AnyValue
134
+ {
135
+ if (args.empty())
136
+ return AnyValue::make_undefined();
137
+ return setter.as_function()->call(thisVal, args);
138
+ };
139
+ props[key] = AnyValue::make_accessor_descriptor(std::nullopt, setFunc, true, true);
140
+ }
141
+ }
142
+ }
143
+
144
+ inline void AnyValue::define_setter(const AnyValue &key, const AnyValue &setter)
145
+ {
146
+ if (key.is_symbol())
147
+ define_setter(key.as_symbol()->key, setter);
148
+ else
149
+ define_setter(key.to_std_string(), setter);
150
+ }
151
+ }
@@ -0,0 +1,246 @@
1
+ #pragma once
2
+
3
+ #include "types.hpp"
4
+ #include "any_value.hpp"
5
+ #include "values/string.hpp"
6
+
7
+ namespace jspp
8
+ {
9
+ const bool AnyValue::is_truthy() const noexcept
10
+ {
11
+ switch (storage.type)
12
+ {
13
+ case JsType::Boolean:
14
+ return storage.boolean;
15
+ case JsType::Number:
16
+ return storage.number != 0.0;
17
+ case JsType::String:
18
+ return !storage.str->value.empty();
19
+ case JsType::Undefined:
20
+ return false;
21
+ case JsType::Null:
22
+ return false;
23
+ case JsType::Uninitialized:
24
+ return false;
25
+ default:
26
+ return true;
27
+ }
28
+ }
29
+
30
+ const bool AnyValue::is_strictly_equal_to_primitive(const AnyValue &other) const noexcept
31
+ {
32
+ if (storage.type == other.storage.type)
33
+ {
34
+ switch (storage.type)
35
+ {
36
+ case JsType::Boolean:
37
+ return storage.boolean == other.storage.boolean;
38
+ case JsType::Number:
39
+ return storage.number == other.storage.number;
40
+ case JsType::String:
41
+ return (storage.str->value == other.storage.str->value);
42
+ case JsType::Array:
43
+ return (storage.array == other.storage.array);
44
+ case JsType::Object:
45
+ return (storage.object == other.storage.object);
46
+ case JsType::Function:
47
+ return (storage.function == other.storage.function);
48
+ case JsType::Iterator:
49
+ return (storage.iterator == other.storage.iterator);
50
+ case JsType::Promise:
51
+ return (storage.promise == other.storage.promise);
52
+ case JsType::Symbol:
53
+ // Symbols are unique by reference/pointer identity
54
+ return (storage.symbol == other.storage.symbol);
55
+ case JsType::DataDescriptor:
56
+ return storage.data_desc == other.storage.data_desc;
57
+ case JsType::AccessorDescriptor:
58
+ return storage.accessor_desc == other.storage.accessor_desc;
59
+ default:
60
+ return true;
61
+ }
62
+ }
63
+ return false;
64
+ }
65
+ const bool AnyValue::is_equal_to_primitive(const AnyValue &other) const noexcept
66
+ {
67
+ // Implements JavaScript's Abstract Equality Comparison Algorithm (==)
68
+ // Step 1: If types are the same, use strict equality (===)
69
+ if (storage.type == other.storage.type)
70
+ {
71
+ return is_strictly_equal_to_primitive(other);
72
+ }
73
+ // Steps 2 & 3: null == undefined
74
+ if ((is_null() && other.is_undefined()) || (is_undefined() && other.is_null()))
75
+ {
76
+ return true;
77
+ }
78
+ // Step 4 & 5: number == string
79
+ if (is_number() && other.is_string())
80
+ {
81
+ double num_this = this->as_double();
82
+ double num_other;
83
+ try
84
+ {
85
+ const std::string &s = other.as_string()->value;
86
+ // JS considers empty string or whitespace-only string to be 0
87
+ if (s.empty() || std::all_of(s.begin(), s.end(), [](unsigned char c)
88
+ { return std::isspace(c); }))
89
+ {
90
+ num_other = 0.0;
91
+ }
92
+ else
93
+ {
94
+ size_t pos;
95
+ num_other = std::stod(s, &pos);
96
+ // Check if the entire string was consumed, allowing for trailing whitespace
97
+ while (pos < s.length() && std::isspace(static_cast<unsigned char>(s[pos])))
98
+ {
99
+ pos++;
100
+ }
101
+ if (pos != s.length())
102
+ {
103
+ num_other = std::numeric_limits<double>::quiet_NaN();
104
+ }
105
+ }
106
+ }
107
+ catch (...)
108
+ {
109
+ num_other = std::numeric_limits<double>::quiet_NaN();
110
+ }
111
+ return num_this == num_other;
112
+ }
113
+ if (is_string() && other.is_number())
114
+ {
115
+ // Delegate to the other operand to avoid code duplication
116
+ return other.is_equal_to_primitive(*this);
117
+ }
118
+ // Step 6 & 7: boolean == any
119
+ if (is_boolean())
120
+ {
121
+ // Convert boolean to number and re-compare
122
+ return AnyValue::make_number(as_boolean() ? 1.0 : 0.0).is_equal_to_primitive(other);
123
+ }
124
+ if (other.is_boolean())
125
+ {
126
+ // Convert boolean to number and re-compare
127
+ return is_equal_to_primitive(AnyValue::make_number(other.as_boolean() ? 1.0 : 0.0));
128
+ }
129
+ // Step 8 & 9: object == (string or number or symbol)
130
+ // Simplified: Objects convert to primitives.
131
+ if ((is_object() || is_array() || is_function() || is_promise() || is_iterator()) && (other.is_string() || other.is_number() || other.is_symbol()))
132
+ {
133
+ // Convert object to primitive (string) and re-compare.
134
+ // This is a simplification of JS's ToPrimitive.
135
+ return AnyValue::make_string(to_std_string()).is_equal_to_primitive(other);
136
+ }
137
+ if ((other.is_object() || other.is_array() || other.is_function() || other.is_promise() || other.is_iterator()) && (is_string() || is_number() || is_symbol()))
138
+ {
139
+ return other.is_equal_to_primitive(*this);
140
+ }
141
+ // Step 10: Datacriptor or accessor descriptor
142
+ if (is_data_descriptor() || is_accessor_descriptor())
143
+ {
144
+ return (*this).is_strictly_equal_to_primitive(other);
145
+ }
146
+ // Step 11: All other cases (e.g., object == null) are false.
147
+ return false;
148
+ }
149
+
150
+ const AnyValue AnyValue::is_strictly_equal_to(const AnyValue &other) const noexcept
151
+ {
152
+ return AnyValue::make_boolean(is_strictly_equal_to_primitive(other));
153
+ }
154
+ const AnyValue AnyValue::is_equal_to(const AnyValue &other) const noexcept
155
+ {
156
+ return AnyValue::make_boolean(is_equal_to_primitive(other));
157
+ }
158
+
159
+ const AnyValue AnyValue::not_strictly_equal_to(const AnyValue &other) const noexcept
160
+ {
161
+ return AnyValue::make_boolean(!is_strictly_equal_to_primitive(other));
162
+ }
163
+ const AnyValue AnyValue::not_equal_to(const AnyValue &other) const noexcept
164
+ {
165
+ return AnyValue::make_boolean(!is_equal_to_primitive(other));
166
+ }
167
+
168
+ const std::string AnyValue::to_std_string() const noexcept
169
+ {
170
+ switch (storage.type)
171
+ {
172
+ case JsType::Undefined:
173
+ return "undefined";
174
+ case JsType::Null:
175
+ return "null";
176
+ case JsType::Boolean:
177
+ return storage.boolean ? "true" : "false";
178
+ case JsType::String:
179
+ return storage.str->to_std_string();
180
+ case JsType::Object:
181
+ return storage.object->to_std_string();
182
+ case JsType::Array:
183
+ return storage.array->to_std_string();
184
+ case JsType::Function:
185
+ return storage.function->to_std_string();
186
+ case JsType::Iterator:
187
+ return storage.iterator->to_std_string();
188
+ case JsType::Promise:
189
+ return storage.promise->to_std_string();
190
+ case JsType::Symbol:
191
+ return storage.symbol->to_std_string();
192
+ case JsType::DataDescriptor:
193
+ return storage.data_desc->value->to_std_string();
194
+ case JsType::AccessorDescriptor:
195
+ {
196
+ if (storage.accessor_desc->get.has_value())
197
+ return storage.accessor_desc->get.value()(*this, {}).to_std_string();
198
+ else
199
+ return "undefined";
200
+ }
201
+ case JsType::Number:
202
+ {
203
+ if (std::isnan(storage.number))
204
+ {
205
+ return "NaN";
206
+ }
207
+ if (std::abs(storage.number) >= 1e21 || (std::abs(storage.number) > 0 && std::abs(storage.number) < 1e-6))
208
+ {
209
+ std::ostringstream oss;
210
+ oss << std::scientific << std::setprecision(4) << storage.number;
211
+ return oss.str();
212
+ }
213
+ else
214
+ {
215
+ std::ostringstream oss;
216
+ oss << std::setprecision(6) << std::fixed << storage.number;
217
+ std::string s = oss.str();
218
+ s.erase(s.find_last_not_of('0') + 1, std::string::npos);
219
+ if (!s.empty() && s.back() == '.')
220
+ {
221
+ s.pop_back();
222
+ }
223
+ return s;
224
+ }
225
+ }
226
+ // Uninitialized and default should not be reached under normal circumstances
227
+ case JsType::Uninitialized:
228
+ return "<uninitialized>";
229
+ default:
230
+ return "";
231
+ }
232
+ }
233
+
234
+ void AnyValue::set_prototype(const AnyValue &proto)
235
+ {
236
+ if (is_object())
237
+ {
238
+ storage.object->proto = std::make_shared<AnyValue>(proto);
239
+ }
240
+ else if (is_function())
241
+ {
242
+ storage.function->proto = std::make_shared<AnyValue>(proto);
243
+ }
244
+ }
245
+
246
+ }
@@ -0,0 +1,31 @@
1
+
2
+ #pragma once
3
+
4
+ #include "types.hpp"
5
+
6
+ namespace jspp
7
+ {
8
+ class AnyValue;
9
+
10
+ struct Exception : std::exception
11
+ {
12
+ std::shared_ptr<AnyValue> data;
13
+
14
+ explicit Exception(std::shared_ptr<AnyValue> d)
15
+ : data(std::move(d)) {}
16
+ explicit Exception(const AnyValue &value)
17
+ : data(std::make_shared<AnyValue>(value)) {}
18
+ explicit Exception(AnyValue &&value)
19
+ : data(std::make_shared<AnyValue>(std::move(value))) {}
20
+
21
+ const char *what() const noexcept override;
22
+ static Exception make_exception(const std::string &message, const std::string &name);
23
+ static AnyValue exception_to_any_value(const std::exception &ex);
24
+
25
+ // --- THROWERS
26
+ static AnyValue throw_unresolved_reference(const std::string &var_name);
27
+ static AnyValue throw_uninitialized_reference(const std::string &var_name);
28
+ static AnyValue throw_immutable_assignment();
29
+ static AnyValue throw_invalid_return_statement();
30
+ };
31
+ }
@@ -0,0 +1,49 @@
1
+ #pragma once
2
+
3
+ #include "types.hpp"
4
+ #include "exception.hpp"
5
+ #include "any_value.hpp"
6
+
7
+ const char *jspp::Exception::what() const noexcept
8
+ {
9
+ return data->to_std_string().c_str();
10
+ }
11
+
12
+ jspp::Exception jspp::Exception::make_exception(const std::string &message, const std::string &name = "Error")
13
+ {
14
+ // Use the global Error object to construct the exception
15
+ std::vector<AnyValue> args = { AnyValue::make_string(message) };
16
+ AnyValue errorObj = ::Error.construct(args);
17
+ errorObj.define_data_property("name", AnyValue::make_string(name));
18
+
19
+ return Exception(errorObj);
20
+ }
21
+ jspp::AnyValue jspp::Exception::exception_to_any_value(const std::exception &ex)
22
+ {
23
+ if (const jspp::Exception *err = dynamic_cast<const jspp::Exception *>(&ex))
24
+ {
25
+ return (*err->data);
26
+ }
27
+ else
28
+ {
29
+ return AnyValue::make_string(ex.what());
30
+ }
31
+ }
32
+
33
+ // --- THROWERS
34
+ jspp::AnyValue jspp::Exception::throw_unresolved_reference(const std::string &var_name)
35
+ {
36
+ throw Exception::make_exception(var_name + " is not defined", "ReferenceError");
37
+ }
38
+ jspp::AnyValue jspp::Exception::throw_uninitialized_reference(const std::string &var_name)
39
+ {
40
+ throw Exception::make_exception("Cannot access '" + var_name + "' before initialization", "ReferenceError");
41
+ }
42
+ jspp::AnyValue jspp::Exception::throw_immutable_assignment()
43
+ {
44
+ throw Exception::make_exception("Assignment to constant variable.", "TypeError");
45
+ }
46
+ jspp::AnyValue jspp::Exception::throw_invalid_return_statement()
47
+ {
48
+ throw Exception::make_exception("Return statements are only valid inside functions.", "SyntaxError");
49
+ }
@@ -1,29 +1,52 @@
1
1
  #pragma once
2
2
 
3
3
  #include "types.hpp"
4
- #include "well_known_symbols.hpp"
4
+ #include "utils/well_known_symbols.hpp"
5
5
 
6
6
  // values
7
+ #include "values/symbol.hpp"
7
8
  #include "values/non_values.hpp"
8
9
  #include "values/object.hpp"
9
10
  #include "values/array.hpp"
10
11
  #include "values/function.hpp"
11
- #include "error.hpp"
12
- #include "descriptors.hpp"
12
+ #include "values/iterator.hpp"
13
+ #include "values/promise.hpp"
14
+ #include "values/string.hpp"
15
+
16
+ #include "exception.hpp"
17
+ #include "values/descriptors.hpp"
13
18
  #include "any_value.hpp"
14
- #include "error_helpers.hpp"
15
- #include "values/prototypes/string.hpp"
19
+ #include "any_value_helpers.hpp"
20
+ #include "any_value_access.hpp"
21
+ #include "any_value_defines.hpp"
22
+ #include "library/error.hpp"
23
+ #include "exception_helpers.hpp"
24
+ #include "scheduler.hpp"
25
+
26
+ #include "values/prototypes/symbol.hpp"
16
27
  #include "values/prototypes/object.hpp"
17
28
  #include "values/prototypes/array.hpp"
18
29
  #include "values/prototypes/function.hpp"
19
- #include "values/operators/object.hpp"
20
- #include "values/operators/array.hpp"
21
- #include "values/operators/function.hpp"
30
+ #include "values/prototypes/iterator.hpp"
31
+ #include "values/prototypes/promise.hpp"
32
+ #include "values/prototypes/string.hpp"
33
+
34
+ #include "values/helpers/symbol.hpp"
35
+ #include "values/helpers/object.hpp"
36
+ #include "values/helpers/array.hpp"
37
+ #include "values/helpers/function.hpp"
38
+ #include "values/helpers/iterator.hpp"
39
+ #include "values/helpers/promise.hpp"
40
+ #include "values/helpers/string.hpp"
22
41
 
23
- // helpers
24
- #include "operators.hpp"
25
- #include "access.hpp"
26
- #include "log_string.hpp"
42
+ // utilities
43
+ #include "utils/operators.hpp"
44
+ #include "utils/access.hpp"
45
+ #include "utils/log_any_value/log_any_value.hpp"
27
46
 
28
47
  // js standard libraries
48
+ #include "library/symbol.hpp"
29
49
  #include "library/console.hpp"
50
+ #include "library/performance.hpp"
51
+ #include "library/promise.hpp"
52
+ #include "library/global.hpp"