@ugo-studio/jspp 0.2.9 → 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 (97) 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/class-handlers.js +6 -6
  8. package/dist/core/codegen/control-flow-handlers.js +10 -9
  9. package/dist/core/codegen/declaration-handlers.js +10 -3
  10. package/dist/core/codegen/destructuring-handlers.js +9 -4
  11. package/dist/core/codegen/expression-handlers.js +40 -29
  12. package/dist/core/codegen/function-handlers.js +78 -12
  13. package/dist/core/codegen/helpers.js +91 -14
  14. package/dist/core/codegen/index.js +4 -2
  15. package/dist/core/codegen/statement-handlers.js +9 -7
  16. package/package.json +2 -2
  17. package/scripts/precompile-headers.ts +249 -50
  18. package/scripts/setup-compiler.ts +63 -63
  19. package/src/prelude/any_value.cpp +636 -0
  20. package/src/prelude/any_value.hpp +369 -362
  21. package/src/prelude/{exception_helpers.hpp → exception.cpp} +53 -53
  22. package/src/prelude/exception.hpp +27 -27
  23. package/src/prelude/iterator_instantiations.hpp +10 -0
  24. package/src/prelude/{index.hpp → jspp.hpp} +10 -16
  25. package/src/prelude/library/array.cpp +191 -0
  26. package/src/prelude/library/array.hpp +13 -186
  27. package/src/prelude/library/console.cpp +125 -0
  28. package/src/prelude/library/console.hpp +24 -112
  29. package/src/prelude/library/error.cpp +100 -0
  30. package/src/prelude/library/error.hpp +13 -113
  31. package/src/prelude/library/function.cpp +69 -0
  32. package/src/prelude/library/function.hpp +11 -10
  33. package/src/prelude/library/global.cpp +96 -0
  34. package/src/prelude/library/global.hpp +12 -28
  35. package/src/prelude/library/global_usings.hpp +15 -0
  36. package/src/prelude/library/math.cpp +258 -0
  37. package/src/prelude/library/math.hpp +26 -308
  38. package/src/prelude/library/object.cpp +379 -0
  39. package/src/prelude/library/object.hpp +14 -276
  40. package/src/prelude/library/performance.cpp +21 -0
  41. package/src/prelude/library/performance.hpp +5 -20
  42. package/src/prelude/library/process.cpp +38 -0
  43. package/src/prelude/library/process.hpp +11 -39
  44. package/src/prelude/library/promise.cpp +131 -0
  45. package/src/prelude/library/promise.hpp +12 -123
  46. package/src/prelude/library/symbol.cpp +56 -0
  47. package/src/prelude/library/symbol.hpp +11 -52
  48. package/src/prelude/library/timer.cpp +88 -0
  49. package/src/prelude/library/timer.hpp +16 -92
  50. package/src/prelude/runtime.cpp +19 -0
  51. package/src/prelude/types.hpp +184 -179
  52. package/src/prelude/utils/access.hpp +502 -411
  53. package/src/prelude/utils/assignment_operators.hpp +99 -99
  54. package/src/prelude/utils/log_any_value/array.hpp +61 -40
  55. package/src/prelude/utils/log_any_value/function.hpp +39 -39
  56. package/src/prelude/utils/log_any_value/object.hpp +60 -3
  57. package/src/prelude/utils/operators.hpp +351 -336
  58. package/src/prelude/utils/operators_primitive.hpp +336 -336
  59. package/src/prelude/utils/well_known_symbols.hpp +24 -24
  60. package/src/prelude/values/array.cpp +1399 -0
  61. package/src/prelude/values/array.hpp +4 -1
  62. package/src/prelude/values/async_iterator.cpp +251 -0
  63. package/src/prelude/values/async_iterator.hpp +111 -83
  64. package/src/prelude/values/function.cpp +262 -0
  65. package/src/prelude/values/function.hpp +62 -82
  66. package/src/prelude/values/iterator.cpp +309 -0
  67. package/src/prelude/values/iterator.hpp +33 -64
  68. package/src/prelude/values/number.cpp +176 -0
  69. package/src/prelude/values/object.cpp +159 -0
  70. package/src/prelude/values/object.hpp +4 -0
  71. package/src/prelude/values/promise.cpp +479 -0
  72. package/src/prelude/values/promise.hpp +79 -72
  73. package/src/prelude/values/prototypes/array.hpp +46 -1336
  74. package/src/prelude/values/prototypes/async_iterator.hpp +19 -61
  75. package/src/prelude/values/prototypes/function.hpp +7 -46
  76. package/src/prelude/values/prototypes/iterator.hpp +25 -201
  77. package/src/prelude/values/prototypes/number.hpp +23 -210
  78. package/src/prelude/values/prototypes/object.hpp +7 -23
  79. package/src/prelude/values/prototypes/promise.hpp +18 -196
  80. package/src/prelude/values/prototypes/string.hpp +39 -542
  81. package/src/prelude/values/prototypes/symbol.hpp +9 -70
  82. package/src/prelude/values/shape.hpp +52 -52
  83. package/src/prelude/values/string.cpp +485 -0
  84. package/src/prelude/values/string.hpp +25 -26
  85. package/src/prelude/values/symbol.cpp +89 -0
  86. package/src/prelude/values/symbol.hpp +101 -101
  87. package/src/prelude/any_value_access.hpp +0 -170
  88. package/src/prelude/any_value_defines.hpp +0 -190
  89. package/src/prelude/any_value_helpers.hpp +0 -374
  90. package/src/prelude/values/helpers/array.hpp +0 -209
  91. package/src/prelude/values/helpers/async_iterator.hpp +0 -275
  92. package/src/prelude/values/helpers/function.hpp +0 -109
  93. package/src/prelude/values/helpers/iterator.hpp +0 -145
  94. package/src/prelude/values/helpers/object.hpp +0 -104
  95. package/src/prelude/values/helpers/promise.hpp +0 -254
  96. package/src/prelude/values/helpers/string.hpp +0 -61
  97. package/src/prelude/values/helpers/symbol.hpp +0 -21
@@ -0,0 +1,125 @@
1
+ #include "jspp.hpp"
2
+ #include "library/console.hpp"
3
+ #include <chrono>
4
+ #include <map>
5
+
6
+ static std::map<std::string, std::chrono::steady_clock::time_point> timers = {};
7
+
8
+ namespace jspp {
9
+ jspp::AnyValue logFn;
10
+ jspp::AnyValue warnFn;
11
+ jspp::AnyValue errorFn;
12
+ jspp::AnyValue timeFn;
13
+ jspp::AnyValue timeEndFn;
14
+ jspp::AnyValue console;
15
+
16
+ static auto format_duration = [](double ms) -> std::string
17
+ {
18
+ std::ostringstream ss;
19
+ if (ms < 1000.0)
20
+ {
21
+ ss << std::fixed << std::setprecision(4) << ms << "ms";
22
+ return ss.str();
23
+ }
24
+ double total_s = ms / 1000.0;
25
+ if (ms < 60000.0)
26
+ {
27
+ ss << std::fixed << std::setprecision(4) << total_s << "s";
28
+ return ss.str();
29
+ }
30
+ if (ms < 3600000.0)
31
+ {
32
+ int minutes = static_cast<int>(ms / 60000.0);
33
+ double seconds = (ms - minutes * 60000.0) / 1000.0;
34
+ ss << minutes << "m " << std::fixed << std::setprecision(4) << seconds << "s";
35
+ return ss.str();
36
+ }
37
+ int hours = static_cast<int>(ms / 3600000.0);
38
+ int minutes = static_cast<int>((ms - hours * 3600000.0) / 60000.0);
39
+ double seconds = (ms - hours * 3600000.0 - minutes * 60000.0) / 1000.0;
40
+ ss << hours << "h " << minutes << "m " << std::fixed << std::setprecision(4) << seconds << "s";
41
+ return ss.str();
42
+ };
43
+
44
+ void init_console() {
45
+ if (!console.is_undefined()) return;
46
+
47
+ logFn = jspp::AnyValue::make_function(
48
+ std::function<AnyValue(AnyValue, std::span<const AnyValue>)>([](jspp::AnyValue thisVal, std::span<const jspp::AnyValue> args)
49
+ {
50
+ for (size_t i = 0; i < args.size(); ++i)
51
+ {
52
+ std::cout << jspp::LogAnyValue::to_log_string(args[i]);
53
+ if (i < args.size() - 1)
54
+ std::cout << " ";
55
+ }
56
+ std::cout << "\n" << std::flush;
57
+ return jspp::Constants::UNDEFINED;
58
+ }), "log");
59
+
60
+ warnFn = jspp::AnyValue::make_function(
61
+ std::function<AnyValue(AnyValue, std::span<const AnyValue>)>([](jspp::AnyValue thisVal, std::span<const jspp::AnyValue> args)
62
+ {
63
+ std::cerr << "\033[33m";
64
+ for (size_t i = 0; i < args.size(); ++i)
65
+ {
66
+ std::cout << jspp::LogAnyValue::to_log_string(args[i]);
67
+ if (i < args.size() - 1)
68
+ std::cout << " ";
69
+ }
70
+ std::cerr << "\033[0m" << "\n" << std::flush;
71
+ return jspp::Constants::UNDEFINED;
72
+ }), "warn");
73
+
74
+ errorFn = jspp::AnyValue::make_function(
75
+ std::function<AnyValue(AnyValue, std::span<const AnyValue>)>([](jspp::AnyValue thisVal, std::span<const jspp::AnyValue> args)
76
+ {
77
+ std::cerr << "\033[31m";
78
+ for (size_t i = 0; i < args.size(); ++i)
79
+ {
80
+ std::cout << jspp::LogAnyValue::to_log_string(args[i]);
81
+ if (i < args.size() - 1)
82
+ std::cout << " ";
83
+ }
84
+ std::cerr << "\033[0m" << "\n" << std::flush;
85
+ return jspp::Constants::UNDEFINED;
86
+ }), "error");
87
+
88
+ timeFn = jspp::AnyValue::make_function(
89
+ std::function<AnyValue(AnyValue, std::span<const AnyValue>)>([](jspp::AnyValue thisVal, std::span<const jspp::AnyValue> args)
90
+ {
91
+ auto start = std::chrono::steady_clock::now();
92
+ auto key_str = args.size() > 0 ? args[0].to_std_string() : "default";
93
+ timers[key_str] = start;
94
+ return jspp::Constants::UNDEFINED;
95
+ }), "time");
96
+
97
+ timeEndFn = jspp::AnyValue::make_function(
98
+ std::function<AnyValue(AnyValue, std::span<const AnyValue>)>([](jspp::AnyValue thisVal, std::span<const jspp::AnyValue> args)
99
+ {
100
+ auto end = std::chrono::steady_clock::now();
101
+ auto key_str = args.size() > 0 ? args[0].to_std_string() : "default";
102
+ auto it = timers.find(key_str);
103
+ if (it != timers.end())
104
+ {
105
+ std::chrono::duration<double, std::milli> duration = end - it->second;
106
+ double ms = duration.count();
107
+ std::cout << "\033[90m" << "[" << format_duration(ms) << "] " << "\033[0m" << key_str << "\n";
108
+ timers.erase(it);
109
+ }
110
+ else
111
+ {
112
+ std::cout << "Timer '" << key_str << "' does not exist.\n";
113
+ }
114
+ return jspp::Constants::UNDEFINED;
115
+ }), "timeEnd");
116
+
117
+ console = jspp::AnyValue::make_object({
118
+ {"log", logFn},
119
+ {"warn", warnFn},
120
+ {"error", errorFn},
121
+ {"time", timeFn},
122
+ {"timeEnd", timeEndFn},
123
+ });
124
+ }
125
+ }
@@ -1,112 +1,24 @@
1
- #pragma once
2
-
3
- #include <chrono>
4
- #include "types.hpp"
5
- #include "values/non_values.hpp"
6
- #include "values/object.hpp"
7
- #include "values/function.hpp"
8
- #include "utils/operators.hpp"
9
- #include "exception.hpp"
10
- #include "utils/log_any_value/log_any_value.hpp"
11
-
12
- #include <cmath>
13
- #include <sstream>
14
- #include <iomanip>
15
-
16
- static std::map<std::string, std::chrono::steady_clock::time_point> timers = {};
17
-
18
- auto logFn = jspp::AnyValue::make_function([](jspp::AnyValue thisVal, std::span<const jspp::AnyValue> args)
19
- {
20
- for (size_t i = 0; i < args.size(); ++i)
21
- {
22
- std::cout << jspp::LogAnyValue::to_log_string(args[i]);
23
- if (i < args.size() - 1)
24
- std::cout << " ";
25
- }
26
- std::cout << "\n" << std::flush;
27
- return jspp::Constants::UNDEFINED; }, "log");
28
- auto warnFn = jspp::AnyValue::make_function([](jspp::AnyValue thisVal, std::span<const jspp::AnyValue> args)
29
- {
30
- std::cerr << "\033[33m";
31
- for (size_t i = 0; i < args.size(); ++i)
32
- {
33
- std::cout << jspp::LogAnyValue::to_log_string(args[i]);
34
- if (i < args.size() - 1)
35
- std::cout << " ";
36
- }
37
- std::cerr << "\033[0m" << "\n" << std::flush; // reset
38
- return jspp::Constants::UNDEFINED; }, "warn");
39
- auto errorFn = jspp::AnyValue::make_function([](jspp::AnyValue thisVal, std::span<const jspp::AnyValue> args)
40
- {
41
- std::cerr << "\033[31m";
42
- for (size_t i = 0; i < args.size(); ++i)
43
- {
44
- std::cout << jspp::LogAnyValue::to_log_string(args[i]);
45
- if (i < args.size() - 1)
46
- std::cout << " ";
47
- }
48
- std::cerr << "\033[0m" << "\n" << std::flush; // reset
49
- return jspp::Constants::UNDEFINED; }, "error");
50
- auto timeFn = jspp::AnyValue::make_function([](jspp::AnyValue thisVal, std::span<const jspp::AnyValue> args)
51
- {
52
- auto start = std::chrono::steady_clock::now(); // capture immediately
53
- auto key_str = args.size() > 0 ? args[0].to_std_string() : "default";
54
- timers[key_str] = start;
55
- return jspp::Constants::UNDEFINED; }, "time");
56
-
57
- // helper to format duration in ms -> ms/s/m/h with nice precision
58
- static auto format_duration = [](double ms) -> std::string
59
- {
60
- std::ostringstream ss;
61
- if (ms < 1000.0)
62
- {
63
- ss << std::fixed << std::setprecision(4) << ms << "ms";
64
- return ss.str();
65
- }
66
- double total_s = ms / 1000.0;
67
- if (ms < 60000.0)
68
- { // less than a minute -> show seconds
69
- ss << std::fixed << std::setprecision(4) << total_s << "s";
70
- return ss.str();
71
- }
72
- if (ms < 3600000.0)
73
- { // less than an hour -> show minutes + seconds
74
- int minutes = static_cast<int>(ms / 60000.0);
75
- double seconds = (ms - minutes * 60000.0) / 1000.0;
76
- ss << minutes << "m " << std::fixed << std::setprecision(4) << seconds << "s";
77
- return ss.str();
78
- }
79
- // hours, minutes, seconds
80
- int hours = static_cast<int>(ms / 3600000.0);
81
- int minutes = static_cast<int>((ms - hours * 3600000.0) / 60000.0);
82
- double seconds = (ms - hours * 3600000.0 - minutes * 60000.0) / 1000.0;
83
- ss << hours << "h " << minutes << "m " << std::fixed << std::setprecision(4) << seconds << "s";
84
- return ss.str();
85
- };
86
-
87
- auto timeEndFn = jspp::AnyValue::make_function([](jspp::AnyValue thisVal, std::span<const jspp::AnyValue> args)
88
- {
89
- auto end = std::chrono::steady_clock::now(); // capture immediately
90
- auto key_str = args.size() > 0 ? args[0].to_std_string() : "default";
91
- auto it = timers.find(key_str);
92
- if (it != timers.end())
93
- {
94
- std::chrono::duration<double, std::milli> duration = end - it->second;
95
- double ms = duration.count();
96
- std::string formatted = format_duration(ms);
97
- std::cout << "\033[90m" << "[" << format_duration(ms) << "] " << "\033[0m" << key_str << "\n";
98
- timers.erase(it); // remove the timer after ending it
99
- }
100
- else
101
- {
102
- std::cout << "Timer '" << key_str << "' does not exist." << "\n";
103
- }
104
- return jspp::Constants::UNDEFINED; }, "timeEnd");
105
-
106
- inline auto console = jspp::AnyValue::make_object({
107
- {"log", logFn},
108
- {"warn", warnFn},
109
- {"error", errorFn},
110
- {"time", timeFn},
111
- {"timeEnd", timeEndFn},
112
- });
1
+ #pragma once
2
+
3
+ #include <chrono>
4
+ #include "types.hpp"
5
+ #include "values/non_values.hpp"
6
+ #include "values/object.hpp"
7
+ #include "values/function.hpp"
8
+ #include "utils/operators.hpp"
9
+ #include "exception.hpp"
10
+ #include "utils/log_any_value/log_any_value.hpp"
11
+
12
+ #include <cmath>
13
+ #include <sstream>
14
+ #include <iomanip>
15
+
16
+ namespace jspp {
17
+ extern AnyValue logFn;
18
+ extern AnyValue warnFn;
19
+ extern AnyValue errorFn;
20
+ extern AnyValue timeFn;
21
+ extern AnyValue timeEndFn;
22
+ extern AnyValue console;
23
+ void init_console();
24
+ }
@@ -0,0 +1,100 @@
1
+ #include "jspp.hpp"
2
+ #include "library/error.hpp"
3
+
4
+ namespace jspp
5
+ {
6
+ jspp::AnyValue Error;
7
+
8
+ auto errorConstructor = [](jspp::AnyValue thisVal, std::span<const jspp::AnyValue> args) -> jspp::AnyValue
9
+ {
10
+ jspp::AnyValue proto = Error.get_own_property("prototype");
11
+ jspp::AnyValue target = thisVal;
12
+ bool is_construct_call = false;
13
+
14
+ if (target.is_object())
15
+ {
16
+ auto obj = target.as_object();
17
+ if (!obj->proto.is_null() && !obj->proto.is_undefined() && is_strictly_equal_to_primitive(obj->proto, proto))
18
+ {
19
+ is_construct_call = true;
20
+ }
21
+ }
22
+
23
+ if (!is_construct_call)
24
+ {
25
+ target = jspp::AnyValue::make_object({}).set_prototype(proto);
26
+ }
27
+
28
+ std::string name = "Error";
29
+ std::string message = "";
30
+ if (!args.empty() && !args[0].is_undefined())
31
+ {
32
+ message = args[0].to_std_string();
33
+ }
34
+
35
+ target.define_data_property("message", jspp::AnyValue::make_string(message), true, false, true);
36
+ target.define_data_property("name", jspp::AnyValue::make_string(name), true, false, true);
37
+ target.define_data_property("stack", jspp::AnyValue::make_string(name + ": " + message + "\n at <unknown>"), true, false, true);
38
+
39
+ if (args.size() > 1 && args[1].is_object())
40
+ {
41
+ jspp::AnyValue cause = args[1].get_own_property("cause");
42
+ if (!cause.is_undefined())
43
+ {
44
+ target.define_data_property("cause", cause, true, false, true);
45
+ }
46
+ }
47
+
48
+ return target;
49
+ };
50
+
51
+ jspp::AnyValue isErrorFn = jspp::AnyValue::make_function(
52
+ std::function<AnyValue(AnyValue, std::span<const AnyValue>)>([](jspp::AnyValue, std::span<const jspp::AnyValue> args) -> jspp::AnyValue
53
+ {
54
+ if (args.empty()) return jspp::Constants::FALSE;
55
+ jspp::AnyValue val = args[0];
56
+ if (!val.is_object()) return jspp::Constants::FALSE;
57
+ jspp::AnyValue proto = Error.get_own_property("prototype");
58
+ if (val.is_object()) {
59
+ auto current = val.as_object()->proto;
60
+ while (!current.is_null()) {
61
+ if (is_strictly_equal_to_primitive(current, proto)) return jspp::Constants::TRUE;
62
+ if (current.is_object()) current = current.as_object()->proto;
63
+ else break;
64
+ }
65
+ }
66
+ return jspp::Constants::FALSE; }),
67
+ "isError");
68
+
69
+ jspp::AnyValue errorToStringFn = jspp::AnyValue::make_function(
70
+ std::function<AnyValue(AnyValue, std::span<const AnyValue>)>([](jspp::AnyValue thisVal, std::span<const jspp::AnyValue> args) -> jspp::AnyValue
71
+ {
72
+ std::string name = "Error";
73
+ std::string msg = "";
74
+ jspp::AnyValue n = thisVal.get_own_property("name");
75
+ if (!n.is_undefined()) name = n.to_std_string();
76
+ jspp::AnyValue m = thisVal.get_own_property("message");
77
+ if (!m.is_undefined()) msg = m.to_std_string();
78
+ if (name.empty() && msg.empty()) return jspp::AnyValue::make_string("Error");
79
+ if (name.empty()) return jspp::AnyValue::make_string(msg);
80
+ if (msg.empty()) return jspp::AnyValue::make_string(name);
81
+ return jspp::AnyValue::make_string(name + ": " + msg); }),
82
+ "toString");
83
+
84
+ struct ErrorInit
85
+ {
86
+ ErrorInit()
87
+ {
88
+ Error = jspp::AnyValue::make_class(
89
+ std::function<AnyValue(AnyValue, std::span<const AnyValue>)>(errorConstructor), "Error");
90
+ auto proto = Error.get_own_property("prototype");
91
+ proto.define_data_property("toString", errorToStringFn, true, false, true);
92
+ proto.define_data_property(jspp::AnyValue::from_symbol(jspp::WellKnownSymbols::toStringTag), errorToStringFn, true, false, true);
93
+ Error.define_data_property("isError", isErrorFn, true, false, true);
94
+ }
95
+ };
96
+ void init_error()
97
+ {
98
+ static ErrorInit errorInit;
99
+ }
100
+ }
@@ -1,113 +1,13 @@
1
- #pragma once
2
-
3
- #include "types.hpp"
4
- #include "any_value.hpp"
5
-
6
- // Declare Error variable
7
- inline jspp::AnyValue Error;
8
-
9
- // Constructor logic
10
- inline auto errorConstructor = [](jspp::AnyValue thisVal, std::span<const jspp::AnyValue> args) -> jspp::AnyValue
11
- {
12
- // Access global Error to get prototype
13
- jspp::AnyValue proto = Error.get_own_property("prototype");
14
-
15
- jspp::AnyValue target = thisVal;
16
- bool is_construct_call = false;
17
-
18
- if (target.is_object())
19
- {
20
- auto obj = target.as_object();
21
- if (!obj->proto.is_null() && !obj->proto.is_undefined() && is_strictly_equal_to_primitive(obj->proto, proto))
22
- {
23
- is_construct_call = true;
24
- }
25
- }
26
-
27
- if (!is_construct_call)
28
- {
29
- target = jspp::AnyValue::make_object_with_proto({}, proto);
30
- }
31
-
32
- std::string name = "Error";
33
- std::string message = "";
34
- if (!args.empty() && !args[0].is_undefined())
35
- {
36
- message = args[0].to_std_string();
37
- }
38
-
39
- target.define_data_property("message", jspp::AnyValue::make_string(message), true, false, true);
40
- target.define_data_property("name", jspp::AnyValue::make_string(name), true, false, true);
41
- target.define_data_property("stack", jspp::AnyValue::make_string(name + ": " + message + "\n at <unknown>"), true, false, true);
42
-
43
- if (args.size() > 1 && args[1].is_object())
44
- {
45
- jspp::AnyValue cause = args[1].get_own_property("cause");
46
- if (!cause.is_undefined())
47
- {
48
- target.define_data_property("cause", cause, true, false, true);
49
- }
50
- }
51
-
52
- return target;
53
- };
54
-
55
- // Static Error.isError(val) implementation
56
- inline auto isErrorFn = jspp::AnyValue::make_function([](jspp::AnyValue, std::span<const jspp::AnyValue> args) -> jspp::AnyValue
57
- {
58
- if (args.empty()) return jspp::Constants::FALSE;
59
-
60
- jspp::AnyValue val = args[0];
61
- if (!val.is_object()) return jspp::Constants::FALSE;
62
-
63
- // Check if it inherits from Error.prototype
64
- // This is essentially 'instanceof Error'
65
- jspp::AnyValue proto = Error.get_own_property("prototype");
66
-
67
- // Walk prototype chain
68
- if (val.is_object()) {
69
- auto current = val.as_object()->proto;
70
- while (!current.is_null()) {
71
- if (is_strictly_equal_to_primitive(current, proto)) return jspp::Constants::TRUE;
72
- if (current.is_object()) current = current.as_object()->proto;
73
- else break;
74
- }
75
- }
76
-
77
- return jspp::Constants::FALSE; }, "isError");
78
-
79
- // toString method for Error.prototype
80
- inline auto errorToStringFn = jspp::AnyValue::make_function([](jspp::AnyValue thisVal, std::span<const jspp::AnyValue> args) -> jspp::AnyValue
81
- {
82
- std::string name = "Error";
83
- std::string msg = "";
84
-
85
- jspp::AnyValue n = thisVal.get_own_property("name");
86
- if (!n.is_undefined()) name = n.to_std_string();
87
-
88
- jspp::AnyValue m = thisVal.get_own_property("message");
89
- if (!m.is_undefined()) msg = m.to_std_string();
90
-
91
- if (name.empty() && msg.empty()) return jspp::AnyValue::make_string("Error");
92
- if (name.empty()) return jspp::AnyValue::make_string(msg);
93
- if (msg.empty()) return jspp::AnyValue::make_string(name);
94
-
95
- return jspp::AnyValue::make_string(name + ": " + msg); }, "toString");
96
-
97
- // Initialize Error class and its prototype
98
- struct ErrorInit
99
- {
100
- ErrorInit()
101
- {
102
- // Initialize Error class
103
- Error = jspp::AnyValue::make_class(errorConstructor, "Error");
104
-
105
- // Define Error.prototype.toString
106
- auto proto = Error.get_own_property("prototype");
107
- proto.define_data_property("toString", errorToStringFn, true, false, true);
108
- proto.define_data_property(jspp::WellKnownSymbols::toStringTag->key, errorToStringFn, true, false, true);
109
-
110
- // Define static Error.isError
111
- Error.define_data_property("isError", isErrorFn, true, false, true);
112
- }
113
- } errorInit;
1
+ #pragma once
2
+
3
+ #include "types.hpp"
4
+ #include "any_value.hpp"
5
+
6
+ namespace jspp {
7
+ extern AnyValue Error;
8
+ void init_error();
9
+ extern AnyValue isErrorFn;
10
+ extern AnyValue errorToStringFn;
11
+ }
12
+
13
+ using jspp::Error;
@@ -0,0 +1,69 @@
1
+ #include "jspp.hpp"
2
+ #include "library/function.hpp"
3
+
4
+ namespace jspp
5
+ {
6
+
7
+ AnyValue Function = jspp::AnyValue::make_class([](jspp::AnyValue thisVal, std::span<const jspp::AnyValue> args) -> jspp::AnyValue
8
+ { return jspp::Constants::UNDEFINED; }, "Function");
9
+
10
+ struct FunctionInit
11
+ {
12
+ FunctionInit()
13
+ {
14
+ auto proto = Function.get_own_property("prototype");
15
+
16
+ // Function.prototype.call
17
+ proto.define_data_property("call", jspp::AnyValue::make_function([](jspp::AnyValue thisVal, std::span<const jspp::AnyValue> args) -> jspp::AnyValue
18
+ {
19
+ if (!thisVal.is_function()) throw jspp::Exception::make_exception("Function.prototype.call called on non-function", "TypeError");
20
+ if (args.empty()) return thisVal.call(jspp::Constants::UNDEFINED, {});
21
+ auto receiver = args[0];
22
+ return thisVal.call(receiver, args.subspan(1)); }, "call"),
23
+ true, false, true);
24
+
25
+ // Function.prototype.apply
26
+ proto.define_data_property("apply", jspp::AnyValue::make_function([](jspp::AnyValue thisVal, std::span<const jspp::AnyValue> args) -> jspp::AnyValue
27
+ {
28
+ if (!thisVal.is_function()) throw jspp::Exception::make_exception("Function.prototype.apply called on non-function", "TypeError");
29
+ auto receiver = args.size() > 0 ? args[0] : jspp::Constants::UNDEFINED;
30
+ auto applyArgs = args.size() > 1 ? args[1] : jspp::Constants::UNDEFINED;
31
+
32
+ if (applyArgs.is_null() || applyArgs.is_undefined()) return thisVal.call(receiver, {});
33
+ if (!applyArgs.is_array()) throw jspp::Exception::make_exception("CreateListFromArrayLike called on non-object", "TypeError");
34
+
35
+ auto arr = applyArgs.as_array();
36
+ std::vector<jspp::AnyValue> vec;
37
+ for(uint64_t i = 0; i < arr->length; ++i) vec.push_back(arr->get_property(static_cast<uint32_t>(i)));
38
+ return thisVal.call(receiver, vec); }, "apply"),
39
+ true, false, true);
40
+
41
+ // Function.prototype.bind
42
+ proto.define_data_property("bind", jspp::AnyValue::make_function([](jspp::AnyValue thisVal, std::span<const jspp::AnyValue> args) -> jspp::AnyValue
43
+ {
44
+ if (!thisVal.is_function()) throw jspp::Exception::make_exception("Function.prototype.bind called on non-function", "TypeError");
45
+ auto receiver = args.size() > 0 ? args[0] : jspp::Constants::UNDEFINED;
46
+ std::vector<jspp::AnyValue> boundArgs(args.begin() + (args.empty() ? 0 : 1), args.end());
47
+
48
+ return jspp::AnyValue::make_function([thisVal, receiver, boundArgs](jspp::AnyValue, std::span<const jspp::AnyValue> callArgs) -> jspp::AnyValue {
49
+ std::vector<jspp::AnyValue> combinedArgs = boundArgs;
50
+ combinedArgs.insert(combinedArgs.end(), callArgs.begin(), callArgs.end());
51
+ return thisVal.call(receiver, combinedArgs);
52
+ }, thisVal.as_function()->name); }, "bind"),
53
+ true, false, true);
54
+
55
+ // Function.prototype.toString
56
+ auto toStringFn = jspp::FunctionPrototypes::get("toString");
57
+ if (toStringFn.has_value())
58
+ {
59
+ proto.define_data_property("toString", toStringFn.value(), true, false, true);
60
+ }
61
+ }
62
+ };
63
+
64
+ void init_function_lib()
65
+ {
66
+ static FunctionInit functionInit;
67
+ }
68
+
69
+ } // namespace jspp
@@ -1,10 +1,11 @@
1
- #pragma once
2
-
3
- #include "types.hpp"
4
- #include "any_value.hpp"
5
-
6
- // Define Function constructor
7
- // In a full implementation, this would support 'new Function(args, body)'
8
- inline auto Function = jspp::AnyValue::make_class([](jspp::AnyValue thisVal, std::span<const jspp::AnyValue> args) -> jspp::AnyValue {
9
- return jspp::Constants::UNDEFINED;
10
- }, "Function");
1
+ #pragma once
2
+
3
+ #include "types.hpp"
4
+ #include "any_value.hpp"
5
+
6
+ namespace jspp {
7
+ extern AnyValue Function;
8
+ void init_function_lib();
9
+ }
10
+
11
+ using jspp::Function;