xbintsc 0.2.9 → 0.3.3
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.
- package/README.md +17 -2
- package/README.zh-CN.md +16 -2
- package/bin/xbintsc.js +49 -10
- package/dist/src/ast/expressions.d.ts +2 -0
- package/dist/src/binder/binder.d.ts +24 -98
- package/dist/src/binder/binder.js +13 -559
- package/dist/src/binder/binder.js.map +1 -1
- package/dist/src/binder/declarations.d.ts +16 -0
- package/dist/src/binder/declarations.js +168 -0
- package/dist/src/binder/declarations.js.map +1 -0
- package/dist/src/binder/helpers.d.ts +11 -0
- package/dist/src/binder/helpers.js +46 -0
- package/dist/src/binder/helpers.js.map +1 -0
- package/dist/src/binder/references.d.ts +21 -0
- package/dist/src/binder/references.js +349 -0
- package/dist/src/binder/references.js.map +1 -0
- package/dist/src/binder/types.d.ts +114 -0
- package/dist/src/binder/types.js +27 -0
- package/dist/src/binder/types.js.map +1 -0
- package/dist/src/cli/main.d.ts +1 -0
- package/dist/src/cli/main.js +40 -0
- package/dist/src/cli/main.js.map +1 -1
- package/dist/src/codegen/generator/calls/access.d.ts +13 -0
- package/dist/src/codegen/generator/calls/access.js +115 -0
- package/dist/src/codegen/generator/calls/access.js.map +1 -0
- package/dist/src/codegen/generator/calls/closures.d.ts +11 -0
- package/dist/src/codegen/generator/calls/closures.js +50 -0
- package/dist/src/codegen/generator/calls/closures.js.map +1 -0
- package/dist/src/codegen/generator/calls/invocation.d.ts +18 -0
- package/dist/src/codegen/generator/calls/invocation.js +242 -0
- package/dist/src/codegen/generator/calls/invocation.js.map +1 -0
- package/dist/src/codegen/generator/calls/literals.d.ts +10 -0
- package/dist/src/codegen/generator/calls/literals.js +69 -0
- package/dist/src/codegen/generator/calls/literals.js.map +1 -0
- package/dist/src/codegen/generator/calls/super.d.ts +10 -0
- package/dist/src/codegen/generator/calls/super.js +47 -0
- package/dist/src/codegen/generator/calls/super.js.map +1 -0
- package/dist/src/codegen/generator/calls.d.ts +15 -24
- package/dist/src/codegen/generator/calls.js +15 -482
- package/dist/src/codegen/generator/calls.js.map +1 -1
- package/dist/src/codegen/generator/context.d.ts +1 -1
- package/dist/src/codegen/generator/context.js +2 -2
- package/dist/src/codegen/generator/context.js.map +1 -1
- package/dist/src/codegen/generator/expressions/assignment.d.ts +13 -0
- package/dist/src/codegen/generator/expressions/assignment.js +203 -0
- package/dist/src/codegen/generator/expressions/assignment.js.map +1 -0
- package/dist/src/codegen/generator/expressions/operators.d.ts +14 -0
- package/dist/src/codegen/generator/expressions/operators.js +163 -0
- package/dist/src/codegen/generator/expressions/operators.js.map +1 -0
- package/dist/src/codegen/generator/expressions/primary.d.ts +17 -0
- package/dist/src/codegen/generator/expressions/primary.js +260 -0
- package/dist/src/codegen/generator/expressions/primary.js.map +1 -0
- package/dist/src/codegen/generator/expressions.d.ts +11 -21
- package/dist/src/codegen/generator/expressions.js +11 -494
- package/dist/src/codegen/generator/expressions.js.map +1 -1
- package/dist/src/codegen/generator/module.js +16 -4
- package/dist/src/codegen/generator/module.js.map +1 -1
- package/dist/src/codegen/generator/state.js +8 -0
- package/dist/src/codegen/generator/state.js.map +1 -1
- package/dist/src/codegen/generator/statements/control-flow.d.ts +14 -0
- package/dist/src/codegen/generator/statements/control-flow.js +199 -0
- package/dist/src/codegen/generator/statements/control-flow.js.map +1 -0
- package/dist/src/codegen/generator/statements/dispatch.d.ts +12 -0
- package/dist/src/codegen/generator/statements/dispatch.js +100 -0
- package/dist/src/codegen/generator/statements/dispatch.js.map +1 -0
- package/dist/src/codegen/generator/statements/loops.d.ts +13 -0
- package/dist/src/codegen/generator/statements/loops.js +152 -0
- package/dist/src/codegen/generator/statements/loops.js.map +1 -0
- package/dist/src/codegen/generator/statements/variables.d.ts +13 -0
- package/dist/src/codegen/generator/statements/variables.js +146 -0
- package/dist/src/codegen/generator/statements/variables.js.map +1 -0
- package/dist/src/codegen/generator/statements.d.ts +13 -21
- package/dist/src/codegen/generator/statements.js +13 -568
- package/dist/src/codegen/generator/statements.js.map +1 -1
- package/dist/src/codegen/generator/tables.js +7 -0
- package/dist/src/codegen/generator/tables.js.map +1 -1
- package/dist/src/codegen/values.d.ts +17 -17
- package/dist/src/codegen/values.js +21 -57
- package/dist/src/codegen/values.js.map +1 -1
- package/dist/src/diagnostics/diagnostic.d.ts +1 -0
- package/dist/src/diagnostics/diagnostic.js +1 -0
- package/dist/src/diagnostics/diagnostic.js.map +1 -1
- package/dist/src/diagnostics/source.d.ts +1 -1
- package/dist/src/diagnostics/source.js +7 -12
- package/dist/src/diagnostics/source.js.map +1 -1
- package/dist/src/driver/compiler.d.ts +4 -0
- package/dist/src/driver/compiler.js +51 -16
- package/dist/src/driver/compiler.js.map +1 -1
- package/dist/src/driver/index.d.ts +5 -2
- package/dist/src/driver/index.js +5 -2
- package/dist/src/driver/index.js.map +1 -1
- package/dist/src/driver/paths.d.ts +20 -0
- package/dist/src/driver/paths.js +49 -0
- package/dist/src/driver/paths.js.map +1 -1
- package/dist/src/driver/runtime-lib.d.ts +18 -0
- package/dist/src/driver/runtime-lib.js +31 -0
- package/dist/src/driver/runtime-lib.js.map +1 -0
- package/dist/src/driver/toolchain-download.d.ts +50 -0
- package/dist/src/driver/toolchain-download.js +76 -0
- package/dist/src/driver/toolchain-download.js.map +1 -0
- package/dist/src/driver/toolchain-provider.d.ts +33 -0
- package/dist/src/driver/toolchain-provider.js +71 -0
- package/dist/src/driver/toolchain-provider.js.map +1 -0
- package/dist/src/driver/toolchain.d.ts +9 -4
- package/dist/src/driver/toolchain.js +6 -10
- package/dist/src/driver/toolchain.js.map +1 -1
- package/dist/src/extensions/node/child_process/index.d.ts +4 -2
- package/dist/src/extensions/node/child_process/index.js +4 -2
- package/dist/src/extensions/node/child_process/index.js.map +1 -1
- package/dist/src/extensions/node/events/index.d.ts +10 -0
- package/dist/src/extensions/node/events/index.js +22 -0
- package/dist/src/extensions/node/events/index.js.map +1 -0
- package/dist/src/extensions/node/index.js +6 -0
- package/dist/src/extensions/node/index.js.map +1 -1
- package/dist/src/extensions/node/querystring/index.d.ts +10 -0
- package/dist/src/extensions/node/querystring/index.js +25 -0
- package/dist/src/extensions/node/querystring/index.js.map +1 -0
- package/dist/src/extensions/node/util/index.d.ts +11 -0
- package/dist/src/extensions/node/util/index.js +41 -0
- package/dist/src/extensions/node/util/index.js.map +1 -0
- package/dist/src/extensions/registry.d.ts +6 -0
- package/dist/src/extensions/registry.js.map +1 -1
- package/dist/src/index.d.ts +1 -1
- package/dist/src/index.js +1 -1
- package/dist/src/index.js.map +1 -1
- package/dist/src/lexer/scanner/identifiers.d.ts +9 -0
- package/dist/src/lexer/scanner/identifiers.js +33 -0
- package/dist/src/lexer/scanner/identifiers.js.map +1 -0
- package/dist/src/lexer/scanner/numbers.d.ts +10 -0
- package/dist/src/lexer/scanner/numbers.js +89 -0
- package/dist/src/lexer/scanner/numbers.js.map +1 -0
- package/dist/src/lexer/scanner/punctuation.d.ts +9 -0
- package/dist/src/lexer/scanner/punctuation.js +151 -0
- package/dist/src/lexer/scanner/punctuation.js.map +1 -0
- package/dist/src/lexer/scanner/regex.d.ts +11 -0
- package/dist/src/lexer/scanner/regex.js +69 -0
- package/dist/src/lexer/scanner/regex.js.map +1 -0
- package/dist/src/lexer/scanner/strings.d.ts +13 -0
- package/dist/src/lexer/scanner/strings.js +118 -0
- package/dist/src/lexer/scanner/strings.js.map +1 -0
- package/dist/src/lexer/scanner.d.ts +20 -27
- package/dist/src/lexer/scanner.js +11 -415
- package/dist/src/lexer/scanner.js.map +1 -1
- package/dist/src/parser/declarations/classes.d.ts +14 -0
- package/dist/src/parser/declarations/classes.js +191 -0
- package/dist/src/parser/declarations/classes.js.map +1 -0
- package/dist/src/parser/declarations/functions.d.ts +17 -0
- package/dist/src/parser/declarations/functions.js +241 -0
- package/dist/src/parser/declarations/functions.js.map +1 -0
- package/dist/src/parser/declarations/type-members.d.ts +16 -0
- package/dist/src/parser/declarations/type-members.js +156 -0
- package/dist/src/parser/declarations/type-members.js.map +1 -0
- package/dist/src/parser/declarations.d.ts +13 -24
- package/dist/src/parser/declarations.js +13 -571
- package/dist/src/parser/declarations.js.map +1 -1
- package/dist/src/parser/helpers.js +13 -4
- package/dist/src/parser/helpers.js.map +1 -1
- package/dist/src/parser/literals.js +10 -1
- package/dist/src/parser/literals.js.map +1 -1
- package/dist/tests/codegen/llvm.test.js +24 -0
- package/dist/tests/codegen/llvm.test.js.map +1 -1
- package/dist/tests/driver/compiler.test.js +3 -0
- package/dist/tests/driver/compiler.test.js.map +1 -1
- package/dist/tests/driver/paths.test.d.ts +1 -0
- package/dist/tests/driver/paths.test.js +26 -0
- package/dist/tests/driver/paths.test.js.map +1 -0
- package/dist/tests/driver/toolchain-download.test.d.ts +1 -0
- package/dist/tests/driver/toolchain-download.test.js +38 -0
- package/dist/tests/driver/toolchain-download.test.js.map +1 -0
- package/dist/tests/driver/toolchain-provider.test.d.ts +1 -0
- package/dist/tests/driver/toolchain-provider.test.js +37 -0
- package/dist/tests/driver/toolchain-provider.test.js.map +1 -0
- package/dist/tests/e2e/compile-node.test.d.ts +7 -0
- package/dist/tests/e2e/compile-node.test.js +123 -0
- package/dist/tests/e2e/compile-node.test.js.map +1 -0
- package/dist/tests/e2e/compile.test.d.ts +4 -1
- package/dist/tests/e2e/compile.test.js +78 -130
- package/dist/tests/e2e/compile.test.js.map +1 -1
- package/dist/tests/e2e/harness.d.ts +36 -0
- package/dist/tests/e2e/harness.js +64 -0
- package/dist/tests/e2e/harness.js.map +1 -0
- package/dist/tests/e2e/node-modules.test.js +60 -0
- package/dist/tests/e2e/node-modules.test.js.map +1 -1
- package/dist/tests/extensions/registry.test.js +4 -0
- package/dist/tests/extensions/registry.test.js.map +1 -1
- package/package.json +5 -3
- package/runtime/ext_node/buffer/buffer.c +12 -552
- package/runtime/ext_node/buffer/parts/byte-access.inc +35 -0
- package/runtime/ext_node/buffer/parts/construction.inc +60 -0
- package/runtime/ext_node/buffer/parts/integer-io.inc +119 -0
- package/runtime/ext_node/buffer/parts/methods.inc +135 -0
- package/runtime/ext_node/buffer/parts/prototype.inc +54 -0
- package/runtime/ext_node/buffer/parts/search.inc +86 -0
- package/runtime/ext_node/buffer/parts/static-api.inc +58 -0
- package/runtime/ext_node/child_process/child_process.c +37 -3
- package/runtime/ext_node/events/events.c +285 -0
- package/runtime/ext_node/http/http.c +11 -736
- package/runtime/ext_node/http/parts/client.inc +290 -0
- package/runtime/ext_node/http/parts/helpers.inc +45 -0
- package/runtime/ext_node/http/parts/prototypes.inc +57 -0
- package/runtime/ext_node/http/parts/response.inc +149 -0
- package/runtime/ext_node/http/parts/server.inc +133 -0
- package/runtime/ext_node/http/parts/string-builder.inc +58 -0
- package/runtime/ext_node/net/net.c +12 -504
- package/runtime/ext_node/net/parts/construction.inc +22 -0
- package/runtime/ext_node/net/parts/platform.inc +60 -0
- package/runtime/ext_node/net/parts/prototypes.inc +35 -0
- package/runtime/ext_node/net/parts/read-loop.inc +58 -0
- package/runtime/ext_node/net/parts/server.inc +131 -0
- package/runtime/ext_node/net/parts/socket-methods.inc +100 -0
- package/runtime/ext_node/net/parts/static-api.inc +93 -0
- package/runtime/ext_node/querystring/querystring.c +251 -0
- package/runtime/ext_node/util/util.c +456 -0
- package/runtime/rt.h +8 -2
- package/runtime/rt_internal.h +34 -0
- package/runtime/xt_bigint/arithmetic.inc +135 -0
- package/runtime/xt_bigint/bits.inc +98 -0
- package/runtime/xt_bigint/bitwise.inc +103 -0
- package/runtime/xt_bigint/compare.inc +30 -0
- package/runtime/xt_bigint/conversions.inc +51 -0
- package/runtime/xt_bigint/division.inc +85 -0
- package/runtime/xt_bigint/format.inc +145 -0
- package/runtime/xt_bigint/helpers.inc +92 -0
- package/runtime/xt_bigint/magnitude.inc +88 -0
- package/runtime/xt_bigint/public.inc +59 -0
- package/runtime/xt_bigint/small-arithmetic.inc +58 -0
- package/runtime/xt_bigint.c +42 -0
- package/runtime/xt_builtins.c +1 -0
- package/runtime/xt_io.c +7 -0
- package/runtime/xt_stdlib/arrays.inc +161 -0
- package/runtime/xt_stdlib/dispatch.inc +116 -0
- package/runtime/xt_stdlib/helpers.inc +23 -0
- package/runtime/xt_stdlib/math.inc +72 -0
- package/runtime/xt_stdlib/strings.inc +178 -0
- package/runtime/xt_stdlib.c +10 -549
- package/runtime/xt_stdlib2/array-statics.inc +37 -0
- package/runtime/xt_stdlib2/arrays.inc +189 -0
- package/runtime/xt_stdlib2/container.inc +23 -0
- package/runtime/xt_stdlib2/date.inc +72 -0
- package/runtime/xt_stdlib2/error.inc +22 -0
- package/runtime/xt_stdlib2/helpers.inc +43 -0
- package/runtime/xt_stdlib2/json.inc +213 -0
- package/runtime/xt_stdlib2/map.inc +95 -0
- package/runtime/xt_stdlib2/number-string-statics.inc +73 -0
- package/runtime/xt_stdlib2/numbers.inc +38 -0
- package/runtime/xt_stdlib2/objects.inc +41 -0
- package/runtime/xt_stdlib2/regexp-match.inc +204 -0
- package/runtime/xt_stdlib2/regexp.inc +20 -0
- package/runtime/xt_stdlib2/set.inc +105 -0
- package/runtime/xt_stdlib2/strings.inc +94 -0
- package/runtime/xt_stdlib2.c +19 -1278
- package/runtime/xt_values.c +155 -12
- package/scripts/build-runtime.ts +109 -0
- package/scripts/fetch-toolchain.ts +101 -0
- package/scripts/package-release.ts +192 -0
- package/src/ast/expressions.ts +2 -0
- package/src/binder/binder.ts +40 -725
- package/src/binder/declarations.ts +203 -0
- package/src/binder/helpers.ts +47 -0
- package/src/binder/references.ts +410 -0
- package/src/binder/types.ts +134 -0
- package/src/cli/main.ts +43 -0
- package/src/codegen/generator/calls/access.ts +139 -0
- package/src/codegen/generator/calls/closures.ts +60 -0
- package/src/codegen/generator/calls/invocation.ts +282 -0
- package/src/codegen/generator/calls/literals.ts +77 -0
- package/src/codegen/generator/calls/super.ts +61 -0
- package/src/codegen/generator/calls.ts +30 -552
- package/src/codegen/generator/context.ts +2 -2
- package/src/codegen/generator/expressions/assignment.ts +226 -0
- package/src/codegen/generator/expressions/operators.ts +182 -0
- package/src/codegen/generator/expressions/primary.ts +304 -0
- package/src/codegen/generator/expressions.ts +22 -553
- package/src/codegen/generator/module.ts +14 -4
- package/src/codegen/generator/state.ts +8 -0
- package/src/codegen/generator/statements/control-flow.ts +225 -0
- package/src/codegen/generator/statements/dispatch.ts +122 -0
- package/src/codegen/generator/statements/loops.ts +173 -0
- package/src/codegen/generator/statements/variables.ts +152 -0
- package/src/codegen/generator/statements.ts +26 -612
- package/src/codegen/generator/tables.ts +7 -0
- package/src/codegen/values.ts +22 -57
- package/src/diagnostics/diagnostic.ts +1 -0
- package/src/diagnostics/source.ts +7 -12
- package/src/driver/compiler.ts +61 -18
- package/src/driver/index.ts +17 -2
- package/src/driver/paths.ts +54 -0
- package/src/driver/runtime-lib.ts +32 -0
- package/src/driver/toolchain-download.ts +108 -0
- package/src/driver/toolchain-provider.ts +91 -0
- package/src/driver/toolchain.ts +29 -11
- package/src/extensions/node/child_process/index.ts +4 -2
- package/src/extensions/node/events/index.ts +27 -0
- package/src/extensions/node/index.ts +6 -0
- package/src/extensions/node/querystring/index.ts +29 -0
- package/src/extensions/node/util/index.ts +48 -0
- package/src/extensions/registry.ts +6 -0
- package/src/index.ts +1 -0
- package/src/lexer/scanner/identifiers.ts +37 -0
- package/src/lexer/scanner/numbers.ts +84 -0
- package/src/lexer/scanner/punctuation.ts +132 -0
- package/src/lexer/scanner/regex.ts +79 -0
- package/src/lexer/scanner/strings.ts +128 -0
- package/src/lexer/scanner.ts +35 -401
- package/src/parser/declarations/classes.ts +215 -0
- package/src/parser/declarations/functions.ts +254 -0
- package/src/parser/declarations/type-members.ts +181 -0
- package/src/parser/declarations.ts +32 -609
- package/src/parser/helpers.ts +13 -6
- package/src/parser/literals.ts +10 -1
- package/scripts/build-runtime.mjs +0 -55
package/runtime/xt_stdlib.c
CHANGED
|
@@ -13,553 +13,14 @@
|
|
|
13
13
|
#include <stdlib.h>
|
|
14
14
|
#include <string.h>
|
|
15
15
|
|
|
16
|
-
/*
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
if (!argv || index < 0 || index >= argc) return XT_UNDEFINED;
|
|
22
|
-
return argv[index];
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
static int xt_same_value_zero(xt_value a, xt_value b) {
|
|
26
|
-
if (XT_IS_NUMBER(a) && XT_IS_NUMBER(b)) {
|
|
27
|
-
double x = xt_to_double(a);
|
|
28
|
-
double y = xt_to_double(b);
|
|
29
|
-
if (isnan(x) && isnan(y)) return 1;
|
|
30
|
-
return x == y;
|
|
31
|
-
}
|
|
32
|
-
return xt_truthy(xt_seq(a, b));
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
xt_array *xt_as_array(xt_value value) {
|
|
36
|
-
if (XT_IS_ARRAY(value)) return (xt_array *)XT_GET_PTR(value);
|
|
37
|
-
return NULL;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
/* -- array methods -------------------------------------------------------- */
|
|
41
|
-
|
|
42
|
-
static xt_value xt_array_pop(xt_value value) {
|
|
43
|
-
xt_array *array = xt_as_array(value);
|
|
44
|
-
if (!array || array->length == 0) return XT_UNDEFINED;
|
|
45
|
-
return array->items[--array->length];
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
static xt_value xt_array_shift(xt_value value) {
|
|
49
|
-
xt_array *array = xt_as_array(value);
|
|
50
|
-
if (!array || array->length == 0) return XT_UNDEFINED;
|
|
51
|
-
xt_value first = array->items[0];
|
|
52
|
-
for (uint32_t i = 1; i < array->length; i++) array->items[i - 1] = array->items[i];
|
|
53
|
-
array->length--;
|
|
54
|
-
return first;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
static xt_value xt_array_unshift(xt_value value, int32_t argc, xt_value *argv) {
|
|
58
|
-
xt_array *array = xt_as_array(value);
|
|
59
|
-
if (!array) return XT_UNDEFINED;
|
|
60
|
-
if (argc <= 0) return xt_number((double)array->length);
|
|
61
|
-
xt_array_reserve(array, array->length + (uint32_t)argc);
|
|
62
|
-
for (uint32_t i = array->length; i-- > 0;) array->items[i + argc] = array->items[i];
|
|
63
|
-
for (int32_t i = 0; i < argc; i++) array->items[i] = argv[i];
|
|
64
|
-
array->length += (uint32_t)argc;
|
|
65
|
-
return xt_number((double)array->length);
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
static void xt_buffer_append(char **out, size_t *length, size_t *capacity, const char *data, size_t size) {
|
|
69
|
-
if (*length + size + 1 > *capacity) {
|
|
70
|
-
while (*length + size + 1 > *capacity) *capacity = (*capacity) * 2;
|
|
71
|
-
*out = (char *)realloc(*out, *capacity);
|
|
72
|
-
if (!*out) abort();
|
|
73
|
-
}
|
|
74
|
-
memcpy(*out + *length, data, size);
|
|
75
|
-
*length += size;
|
|
76
|
-
(*out)[*length] = '\0';
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
static xt_value xt_array_join(xt_value value, xt_value separator) {
|
|
80
|
-
xt_array *array = xt_as_array(value);
|
|
81
|
-
if (!array) return xt_string_from_cstr("");
|
|
82
|
-
xt_string *sep = xt_as_string(xt_to_string(separator == XT_UNDEFINED ? xt_string_from_cstr(",") : separator));
|
|
83
|
-
size_t capacity = 32;
|
|
84
|
-
size_t length = 0;
|
|
85
|
-
char *out = (char *)malloc(capacity);
|
|
86
|
-
if (!out) abort();
|
|
87
|
-
out[0] = '\0';
|
|
88
|
-
for (uint32_t i = 0; i < array->length; i++) {
|
|
89
|
-
if (i > 0) xt_buffer_append(&out, &length, &capacity, sep->data, sep->length);
|
|
90
|
-
xt_value item = array->items[i];
|
|
91
|
-
if (item == XT_UNDEFINED || item == XT_NULL) continue;
|
|
92
|
-
xt_string *str = xt_as_string(xt_to_string(item));
|
|
93
|
-
xt_buffer_append(&out, &length, &capacity, str->data, str->length);
|
|
94
|
-
}
|
|
95
|
-
xt_value result = xt_string_new(out, length);
|
|
96
|
-
free(out);
|
|
97
|
-
return result;
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
static void xt_normalize_slice(int32_t len, int32_t *start, int32_t *end) {
|
|
101
|
-
if (*start < 0) *start += len;
|
|
102
|
-
if (*start < 0) *start = 0;
|
|
103
|
-
if (*start > len) *start = len;
|
|
104
|
-
if (*end < 0) *end += len;
|
|
105
|
-
if (*end < 0) *end = 0;
|
|
106
|
-
if (*end > len) *end = len;
|
|
107
|
-
if (*end < *start) *end = *start;
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
static xt_value xt_array_slice(xt_value value, xt_value startValue, xt_value endValue) {
|
|
111
|
-
xt_array *array = xt_as_array(value);
|
|
112
|
-
if (!array) return XT_UNDEFINED;
|
|
113
|
-
int32_t len = (int32_t)array->length;
|
|
114
|
-
int32_t start = startValue == XT_UNDEFINED ? 0 : xt_to_int32(startValue);
|
|
115
|
-
int32_t end = endValue == XT_UNDEFINED ? len : xt_to_int32(endValue);
|
|
116
|
-
xt_normalize_slice(len, &start, &end);
|
|
117
|
-
return xt_array_new(end - start, array->items + start);
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
static xt_value xt_array_index_of(xt_value value, xt_value needle, xt_value fromValue, int sameValueZero) {
|
|
121
|
-
xt_array *array = xt_as_array(value);
|
|
122
|
-
if (!array) return xt_number(-1);
|
|
123
|
-
int32_t from = fromValue == XT_UNDEFINED ? 0 : xt_to_int32(fromValue);
|
|
124
|
-
if (from < 0) from += (int32_t)array->length;
|
|
125
|
-
if (from < 0) from = 0;
|
|
126
|
-
for (uint32_t i = (uint32_t)from; i < array->length; i++) {
|
|
127
|
-
int equal = sameValueZero ? xt_same_value_zero(array->items[i], needle) : xt_truthy(xt_seq(array->items[i], needle));
|
|
128
|
-
if (equal) return xt_number((double)i);
|
|
129
|
-
}
|
|
130
|
-
return xt_number(-1);
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
static xt_value xt_array_concat(xt_value value, int32_t argc, xt_value *argv) {
|
|
134
|
-
xt_array *array = xt_as_array(value);
|
|
135
|
-
xt_value result = xt_array_new(0, NULL);
|
|
136
|
-
if (!array) return result;
|
|
137
|
-
for (uint32_t i = 0; i < array->length; i++) xt_array_push(result, array->items[i]);
|
|
138
|
-
for (int32_t i = 0; i < argc; i++) {
|
|
139
|
-
if (XT_IS_ARRAY(argv[i])) {
|
|
140
|
-
xt_array *other = xt_as_array(argv[i]);
|
|
141
|
-
for (uint32_t j = 0; j < other->length; j++) xt_array_push(result, other->items[j]);
|
|
142
|
-
} else {
|
|
143
|
-
xt_array_push(result, argv[i]);
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
return result;
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
static xt_value xt_array_for_each(xt_value value, xt_value fn) {
|
|
150
|
-
xt_array *array = xt_as_array(value);
|
|
151
|
-
if (!array) return XT_UNDEFINED;
|
|
152
|
-
for (uint32_t i = 0; i < array->length; i++) {
|
|
153
|
-
xt_value args[3] = {array->items[i], xt_number((double)i), value};
|
|
154
|
-
xt_closure_call(fn, 3, args);
|
|
155
|
-
}
|
|
156
|
-
return XT_UNDEFINED;
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
static xt_value xt_array_map(xt_value value, xt_value fn) {
|
|
160
|
-
xt_array *array = xt_as_array(value);
|
|
161
|
-
xt_value result = xt_array_new(0, NULL);
|
|
162
|
-
if (!array) return result;
|
|
163
|
-
for (uint32_t i = 0; i < array->length; i++) {
|
|
164
|
-
xt_value args[3] = {array->items[i], xt_number((double)i), value};
|
|
165
|
-
xt_array_push(result, xt_closure_call(fn, 3, args));
|
|
166
|
-
}
|
|
167
|
-
return result;
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
static xt_value xt_array_filter(xt_value value, xt_value fn) {
|
|
171
|
-
xt_array *array = xt_as_array(value);
|
|
172
|
-
xt_value result = xt_array_new(0, NULL);
|
|
173
|
-
if (!array) return result;
|
|
174
|
-
for (uint32_t i = 0; i < array->length; i++) {
|
|
175
|
-
xt_value args[3] = {array->items[i], xt_number((double)i), value};
|
|
176
|
-
if (xt_truthy(xt_closure_call(fn, 3, args))) xt_array_push(result, array->items[i]);
|
|
177
|
-
}
|
|
178
|
-
return result;
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
static xt_value xt_array_reduce(xt_value value, xt_value fn, int32_t hasInitial, xt_value initial) {
|
|
182
|
-
xt_array *array = xt_as_array(value);
|
|
183
|
-
if (!array) return XT_UNDEFINED;
|
|
184
|
-
uint32_t i = 0;
|
|
185
|
-
xt_value accumulator;
|
|
186
|
-
if (hasInitial) {
|
|
187
|
-
accumulator = initial;
|
|
188
|
-
} else if (array->length > 0) {
|
|
189
|
-
accumulator = array->items[0];
|
|
190
|
-
i = 1;
|
|
191
|
-
} else {
|
|
192
|
-
xt_throw(xt_string_from_cstr("TypeError: Reduce of empty array with no initial value"));
|
|
193
|
-
return XT_UNDEFINED;
|
|
194
|
-
}
|
|
195
|
-
for (; i < array->length; i++) {
|
|
196
|
-
xt_value args[4] = {accumulator, array->items[i], xt_number((double)i), value};
|
|
197
|
-
accumulator = xt_closure_call(fn, 4, args);
|
|
198
|
-
}
|
|
199
|
-
return accumulator;
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
/* -- string methods ------------------------------------------------------- */
|
|
203
|
-
|
|
204
|
-
static int32_t xt_string_find(xt_string *haystack, xt_string *needle, int32_t from) {
|
|
205
|
-
if (from < 0) from = 0;
|
|
206
|
-
if ((uint32_t)from > haystack->length) return -1;
|
|
207
|
-
if (needle->length == 0) return from;
|
|
208
|
-
for (uint32_t i = (uint32_t)from; i + needle->length <= haystack->length; i++) {
|
|
209
|
-
if (memcmp(haystack->data + i, needle->data, needle->length) == 0) return (int32_t)i;
|
|
210
|
-
}
|
|
211
|
-
return -1;
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
static xt_value xt_string_char_at(xt_value value, xt_value indexValue) {
|
|
215
|
-
xt_string *s = xt_as_string(value);
|
|
216
|
-
if (!s) return xt_string_from_cstr("");
|
|
217
|
-
int32_t index = xt_to_int32(indexValue);
|
|
218
|
-
if (index < 0 || (uint32_t)index >= s->length) return xt_string_from_cstr("");
|
|
219
|
-
return xt_string_new(s->data + index, 1);
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
static xt_value xt_string_char_code_at(xt_value value, xt_value indexValue) {
|
|
223
|
-
xt_string *s = xt_as_string(value);
|
|
224
|
-
if (!s) return xt_number(NAN);
|
|
225
|
-
int32_t index = xt_to_int32(indexValue);
|
|
226
|
-
if (index < 0 || (uint32_t)index >= s->length) return xt_number(NAN);
|
|
227
|
-
return xt_number((double)(unsigned char)s->data[index]);
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
static xt_value xt_string_index_of(xt_value value, xt_value needleValue, xt_value fromValue) {
|
|
231
|
-
xt_string *s = xt_as_string(value);
|
|
232
|
-
if (!s) return xt_number(-1);
|
|
233
|
-
xt_string *needle = xt_as_string(xt_to_string(needleValue));
|
|
234
|
-
int32_t from = fromValue == XT_UNDEFINED ? 0 : xt_to_int32(fromValue);
|
|
235
|
-
return xt_number((double)xt_string_find(s, needle, from));
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
static xt_value xt_string_slice(xt_value value, xt_value startValue, xt_value endValue) {
|
|
239
|
-
xt_string *s = xt_as_string(value);
|
|
240
|
-
if (!s) return xt_string_from_cstr("");
|
|
241
|
-
int32_t len = (int32_t)s->length;
|
|
242
|
-
int32_t start = startValue == XT_UNDEFINED ? 0 : xt_to_int32(startValue);
|
|
243
|
-
int32_t end = endValue == XT_UNDEFINED ? len : xt_to_int32(endValue);
|
|
244
|
-
xt_normalize_slice(len, &start, &end);
|
|
245
|
-
return xt_string_new(s->data + start, (size_t)(end - start));
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
static xt_value xt_string_substring(xt_value value, xt_value startValue, xt_value endValue) {
|
|
249
|
-
xt_string *s = xt_as_string(value);
|
|
250
|
-
if (!s) return xt_string_from_cstr("");
|
|
251
|
-
int32_t len = (int32_t)s->length;
|
|
252
|
-
int32_t start = startValue == XT_UNDEFINED ? 0 : xt_to_int32(startValue);
|
|
253
|
-
int32_t end = endValue == XT_UNDEFINED ? len : xt_to_int32(endValue);
|
|
254
|
-
if (start < 0) start = 0;
|
|
255
|
-
if (start > len) start = len;
|
|
256
|
-
if (end < 0) end = 0;
|
|
257
|
-
if (end > len) end = len;
|
|
258
|
-
if (start > end) {
|
|
259
|
-
int32_t swap = start;
|
|
260
|
-
start = end;
|
|
261
|
-
end = swap;
|
|
262
|
-
}
|
|
263
|
-
return xt_string_new(s->data + start, (size_t)(end - start));
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
static xt_value xt_string_substr(xt_value value, xt_value startValue, xt_value lengthValue) {
|
|
267
|
-
xt_string *s = xt_as_string(value);
|
|
268
|
-
if (!s) return xt_string_from_cstr("");
|
|
269
|
-
int32_t len = (int32_t)s->length;
|
|
270
|
-
int32_t start = startValue == XT_UNDEFINED ? 0 : xt_to_int32(startValue);
|
|
271
|
-
if (start < 0) start += len;
|
|
272
|
-
if (start < 0) start = 0;
|
|
273
|
-
if (start > len) start = len;
|
|
274
|
-
int32_t length = lengthValue == XT_UNDEFINED ? len - start : xt_to_int32(lengthValue);
|
|
275
|
-
if (length < 0) length = 0;
|
|
276
|
-
if (start + length > len) length = len - start;
|
|
277
|
-
return xt_string_new(s->data + start, (size_t)length);
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
static xt_value xt_string_split(xt_value value, xt_value separatorValue) {
|
|
281
|
-
xt_value result = xt_array_new(0, NULL);
|
|
282
|
-
xt_string *s = xt_as_string(value);
|
|
283
|
-
if (!s) return result;
|
|
284
|
-
if (separatorValue == XT_UNDEFINED) {
|
|
285
|
-
xt_array_push(result, value);
|
|
286
|
-
return result;
|
|
287
|
-
}
|
|
288
|
-
xt_string *sep = xt_as_string(xt_to_string(separatorValue));
|
|
289
|
-
if (sep->length == 0) {
|
|
290
|
-
for (uint32_t i = 0; i < s->length; i++) xt_array_push(result, xt_string_new(s->data + i, 1));
|
|
291
|
-
return result;
|
|
292
|
-
}
|
|
293
|
-
uint32_t start = 0;
|
|
294
|
-
uint32_t i = 0;
|
|
295
|
-
while (i + sep->length <= s->length) {
|
|
296
|
-
if (memcmp(s->data + i, sep->data, sep->length) == 0) {
|
|
297
|
-
xt_array_push(result, xt_string_new(s->data + start, i - start));
|
|
298
|
-
i += sep->length;
|
|
299
|
-
start = i;
|
|
300
|
-
} else {
|
|
301
|
-
i++;
|
|
302
|
-
}
|
|
303
|
-
}
|
|
304
|
-
xt_array_push(result, xt_string_new(s->data + start, s->length - start));
|
|
305
|
-
return result;
|
|
306
|
-
}
|
|
307
|
-
|
|
308
|
-
static xt_value xt_string_case(xt_value value, int upper) {
|
|
309
|
-
xt_string *s = xt_as_string(value);
|
|
310
|
-
if (!s) return value;
|
|
311
|
-
xt_string *out = xt_string_alloc(s->length);
|
|
312
|
-
for (uint32_t i = 0; i < s->length; i++) {
|
|
313
|
-
unsigned char c = (unsigned char)s->data[i];
|
|
314
|
-
out->data[i] = (char)(upper ? toupper((int)c) : tolower((int)c));
|
|
315
|
-
}
|
|
316
|
-
return XT_FROM_PTR(XT_TAG_STRING, out);
|
|
317
|
-
}
|
|
318
|
-
|
|
319
|
-
static xt_value xt_string_trim(xt_value value) {
|
|
320
|
-
xt_string *s = xt_as_string(value);
|
|
321
|
-
if (!s) return value;
|
|
322
|
-
uint32_t start = 0;
|
|
323
|
-
uint32_t end = s->length;
|
|
324
|
-
while (start < end && isspace((unsigned char)s->data[start])) start++;
|
|
325
|
-
while (end > start && isspace((unsigned char)s->data[end - 1])) end--;
|
|
326
|
-
return xt_string_new(s->data + start, end - start);
|
|
327
|
-
}
|
|
328
|
-
|
|
329
|
-
static xt_value xt_string_replace(xt_value value, xt_value searchValue, xt_value replacementValue) {
|
|
330
|
-
if (xt_is_regexp(searchValue)) return xt_regexp_replace(value, searchValue, replacementValue);
|
|
331
|
-
xt_string *s = xt_as_string(value);
|
|
332
|
-
if (!s) return value;
|
|
333
|
-
xt_string *search = xt_as_string(xt_to_string(searchValue));
|
|
334
|
-
xt_string *replacement = xt_as_string(xt_to_string(replacementValue));
|
|
335
|
-
int32_t at = xt_string_find(s, search, 0);
|
|
336
|
-
if (at < 0) return value;
|
|
337
|
-
size_t total = s->length - search->length + replacement->length;
|
|
338
|
-
xt_string *out = xt_string_alloc(total);
|
|
339
|
-
memcpy(out->data, s->data, (size_t)at);
|
|
340
|
-
memcpy(out->data + at, replacement->data, replacement->length);
|
|
341
|
-
memcpy(out->data + at + replacement->length, s->data + at + search->length,
|
|
342
|
-
s->length - (size_t)at - search->length);
|
|
343
|
-
return XT_FROM_PTR(XT_TAG_STRING, out);
|
|
344
|
-
}
|
|
345
|
-
|
|
346
|
-
static xt_value xt_string_repeat(xt_value value, xt_value countValue) {
|
|
347
|
-
xt_string *s = xt_as_string(value);
|
|
348
|
-
if (!s) return value;
|
|
349
|
-
int32_t count = xt_to_int32(countValue);
|
|
350
|
-
if (count < 0) {
|
|
351
|
-
xt_throw(xt_string_from_cstr("RangeError: Invalid count value"));
|
|
352
|
-
return XT_UNDEFINED;
|
|
353
|
-
}
|
|
354
|
-
xt_string *out = xt_string_alloc((size_t)s->length * (size_t)count);
|
|
355
|
-
for (int32_t i = 0; i < count; i++) memcpy(out->data + (size_t)i * s->length, s->data, s->length);
|
|
356
|
-
return XT_FROM_PTR(XT_TAG_STRING, out);
|
|
357
|
-
}
|
|
358
|
-
|
|
359
|
-
static xt_value xt_string_starts_with(xt_value value, xt_value searchValue) {
|
|
360
|
-
xt_string *s = xt_as_string(value);
|
|
361
|
-
if (!s) return XT_FALSE;
|
|
362
|
-
xt_string *search = xt_as_string(xt_to_string(searchValue));
|
|
363
|
-
if (search->length > s->length) return XT_FALSE;
|
|
364
|
-
return xt_bool(memcmp(s->data, search->data, search->length) == 0);
|
|
365
|
-
}
|
|
366
|
-
|
|
367
|
-
static xt_value xt_string_ends_with(xt_value value, xt_value searchValue) {
|
|
368
|
-
xt_string *s = xt_as_string(value);
|
|
369
|
-
if (!s) return XT_FALSE;
|
|
370
|
-
xt_string *search = xt_as_string(xt_to_string(searchValue));
|
|
371
|
-
if (search->length > s->length) return XT_FALSE;
|
|
372
|
-
return xt_bool(memcmp(s->data + s->length - search->length, search->data, search->length) == 0);
|
|
373
|
-
}
|
|
374
|
-
|
|
375
|
-
static xt_value xt_string_concat_args(xt_value value, int32_t argc, xt_value *argv) {
|
|
376
|
-
xt_value result = XT_IS_STRING(value) ? value : xt_to_string(value);
|
|
377
|
-
for (int32_t i = 0; i < argc; i++) result = xt_add(result, xt_to_string(argv[i]));
|
|
378
|
-
return result;
|
|
379
|
-
}
|
|
380
|
-
|
|
381
|
-
/* -- method dispatch ------------------------------------------------------ */
|
|
382
|
-
|
|
383
|
-
static xt_value xt_array_method(xt_value target, const char *method, int32_t argc, xt_value *argv, int *handled) {
|
|
384
|
-
*handled = 1;
|
|
385
|
-
if (strcmp(method, "push") == 0) {
|
|
386
|
-
xt_value result = xt_number(0);
|
|
387
|
-
for (int32_t i = 0; i < argc; i++) result = xt_array_push(target, argv[i]);
|
|
388
|
-
if (argc == 0) result = xt_number((double)xt_as_array(target)->length);
|
|
389
|
-
return result;
|
|
390
|
-
}
|
|
391
|
-
if (strcmp(method, "pop") == 0) return xt_array_pop(target);
|
|
392
|
-
if (strcmp(method, "shift") == 0) return xt_array_shift(target);
|
|
393
|
-
if (strcmp(method, "unshift") == 0) return xt_array_unshift(target, argc, argv);
|
|
394
|
-
if (strcmp(method, "join") == 0) return xt_array_join(target, xt_arg_at(argc, argv, 0));
|
|
395
|
-
if (strcmp(method, "slice") == 0) return xt_array_slice(target, xt_arg_at(argc, argv, 0), xt_arg_at(argc, argv, 1));
|
|
396
|
-
if (strcmp(method, "indexOf") == 0) return xt_array_index_of(target, xt_arg_at(argc, argv, 0), xt_arg_at(argc, argv, 1), 0);
|
|
397
|
-
if (strcmp(method, "includes") == 0) return xt_bool(xt_truthy(xt_ne(xt_array_index_of(target, xt_arg_at(argc, argv, 0), xt_arg_at(argc, argv, 1), 1), xt_number(-1))));
|
|
398
|
-
if (strcmp(method, "concat") == 0) return xt_array_concat(target, argc, argv);
|
|
399
|
-
if (strcmp(method, "forEach") == 0) return xt_array_for_each(target, xt_arg_at(argc, argv, 0));
|
|
400
|
-
if (strcmp(method, "map") == 0) return xt_array_map(target, xt_arg_at(argc, argv, 0));
|
|
401
|
-
if (strcmp(method, "filter") == 0) return xt_array_filter(target, xt_arg_at(argc, argv, 0));
|
|
402
|
-
if (strcmp(method, "reduce") == 0) {
|
|
403
|
-
int32_t hasInitial = argc >= 2 ? 1 : 0;
|
|
404
|
-
return xt_array_reduce(target, xt_arg_at(argc, argv, 0), hasInitial, xt_arg_at(argc, argv, 1));
|
|
405
|
-
}
|
|
406
|
-
if (strcmp(method, "reverse") == 0) {
|
|
407
|
-
xt_array *array = xt_as_array(target);
|
|
408
|
-
for (uint32_t i = 0; i + 1 < array->length; i++, array->length--) {
|
|
409
|
-
xt_value tmp = array->items[i];
|
|
410
|
-
array->items[i] = array->items[array->length - 1];
|
|
411
|
-
array->items[array->length - 1] = tmp;
|
|
412
|
-
}
|
|
413
|
-
return target;
|
|
414
|
-
}
|
|
415
|
-
*handled = 0;
|
|
416
|
-
return XT_UNDEFINED;
|
|
417
|
-
}
|
|
418
|
-
|
|
419
|
-
static xt_value xt_string_method(xt_value target, const char *method, int32_t argc, xt_value *argv, int *handled) {
|
|
420
|
-
*handled = 1;
|
|
421
|
-
if (strcmp(method, "charAt") == 0) return xt_string_char_at(target, xt_arg_at(argc, argv, 0));
|
|
422
|
-
if (strcmp(method, "charCodeAt") == 0) return xt_string_char_code_at(target, xt_arg_at(argc, argv, 0));
|
|
423
|
-
if (strcmp(method, "indexOf") == 0) return xt_string_index_of(target, xt_arg_at(argc, argv, 0), xt_arg_at(argc, argv, 1));
|
|
424
|
-
if (strcmp(method, "includes") == 0) return xt_bool(xt_truthy(xt_ne(xt_string_index_of(target, xt_arg_at(argc, argv, 0), xt_arg_at(argc, argv, 1)), xt_number(-1))));
|
|
425
|
-
if (strcmp(method, "slice") == 0) return xt_string_slice(target, xt_arg_at(argc, argv, 0), xt_arg_at(argc, argv, 1));
|
|
426
|
-
if (strcmp(method, "substring") == 0) return xt_string_substring(target, xt_arg_at(argc, argv, 0), xt_arg_at(argc, argv, 1));
|
|
427
|
-
if (strcmp(method, "substr") == 0) return xt_string_substr(target, xt_arg_at(argc, argv, 0), xt_arg_at(argc, argv, 1));
|
|
428
|
-
if (strcmp(method, "split") == 0) return xt_string_split(target, xt_arg_at(argc, argv, 0));
|
|
429
|
-
if (strcmp(method, "toUpperCase") == 0) return xt_string_case(target, 1);
|
|
430
|
-
if (strcmp(method, "toLowerCase") == 0) return xt_string_case(target, 0);
|
|
431
|
-
if (strcmp(method, "trim") == 0) return xt_string_trim(target);
|
|
432
|
-
if (strcmp(method, "replace") == 0) return xt_string_replace(target, xt_arg_at(argc, argv, 0), xt_arg_at(argc, argv, 1));
|
|
433
|
-
if (strcmp(method, "repeat") == 0) return xt_string_repeat(target, xt_arg_at(argc, argv, 0));
|
|
434
|
-
if (strcmp(method, "startsWith") == 0) return xt_string_starts_with(target, xt_arg_at(argc, argv, 0));
|
|
435
|
-
if (strcmp(method, "endsWith") == 0) return xt_string_ends_with(target, xt_arg_at(argc, argv, 0));
|
|
436
|
-
if (strcmp(method, "concat") == 0) return xt_string_concat_args(target, argc, argv);
|
|
437
|
-
*handled = 0;
|
|
438
|
-
return XT_UNDEFINED;
|
|
439
|
-
}
|
|
440
|
-
|
|
441
|
-
xt_value xt_call_method(xt_value target, xt_value name, int32_t argc, xt_value *argv) {
|
|
442
|
-
const char *method = xt_string_data(name);
|
|
443
|
-
if (!method) return XT_UNDEFINED;
|
|
444
|
-
int handled = 0;
|
|
445
|
-
if (XT_IS_OBJECT(target)) {
|
|
446
|
-
xt_object *obj = (xt_object *)XT_GET_PTR(target);
|
|
447
|
-
int kind = obj->header.kind;
|
|
448
|
-
if (kind == XT_OBJECT_KIND_PROMISE) {
|
|
449
|
-
xt_value result = xt_promise_method(target, method, argc, argv, &handled);
|
|
450
|
-
if (handled) return result;
|
|
451
|
-
}
|
|
452
|
-
if (kind != XT_OBJECT_KIND_OBJECT && kind != XT_OBJECT_KIND_FUNCTION) {
|
|
453
|
-
xt_value result = xt_ext_container_method(target, method, argc, argv, &handled);
|
|
454
|
-
if (handled) return result;
|
|
455
|
-
}
|
|
456
|
-
xt_value fn = xt_object_get(target, name);
|
|
457
|
-
if (XT_IS_FUNCTION(fn)) return xt_call_with_this(fn, target, argc, argv);
|
|
458
|
-
xt_value result = xt_ext_object_method(target, method, argc, argv, &handled);
|
|
459
|
-
if (handled) return result;
|
|
460
|
-
{
|
|
461
|
-
char message[256];
|
|
462
|
-
snprintf(message, sizeof(message), "TypeError: object has no callable method '%s'", method);
|
|
463
|
-
xt_throw(xt_string_from_cstr(message));
|
|
464
|
-
}
|
|
465
|
-
return XT_UNDEFINED;
|
|
466
|
-
}
|
|
467
|
-
if (XT_IS_FUNCTION(target)) {
|
|
468
|
-
xt_value fn = xt_object_get(target, name);
|
|
469
|
-
if (XT_IS_FUNCTION(fn)) return xt_call_with_this(fn, target, argc, argv);
|
|
470
|
-
{
|
|
471
|
-
char message[256];
|
|
472
|
-
snprintf(message, sizeof(message), "TypeError: function has no callable method '%s'", method);
|
|
473
|
-
xt_throw(xt_string_from_cstr(message));
|
|
474
|
-
}
|
|
475
|
-
return XT_UNDEFINED;
|
|
476
|
-
}
|
|
477
|
-
if (XT_IS_ARRAY(target)) {
|
|
478
|
-
xt_value result = xt_ext_array_method(target, method, argc, argv, &handled);
|
|
479
|
-
if (handled) return result;
|
|
480
|
-
return xt_array_method(target, method, argc, argv, &handled);
|
|
481
|
-
}
|
|
482
|
-
if (XT_IS_STRING(target)) {
|
|
483
|
-
xt_value result = xt_ext_string_method(target, method, argc, argv, &handled);
|
|
484
|
-
if (handled) return result;
|
|
485
|
-
return xt_string_method(target, method, argc, argv, &handled);
|
|
486
|
-
}
|
|
487
|
-
if (XT_IS_NUMBER(target)) {
|
|
488
|
-
xt_value result = xt_ext_number_method(target, method, argc, argv, &handled);
|
|
489
|
-
if (handled) return result;
|
|
490
|
-
}
|
|
491
|
-
return XT_UNDEFINED;
|
|
492
|
-
}
|
|
493
|
-
|
|
494
|
-
/* ------------------------------------------------------------------------- */
|
|
495
|
-
/* Math */
|
|
496
|
-
/* ------------------------------------------------------------------------- */
|
|
497
|
-
|
|
498
|
-
xt_value xt_math_call(xt_value name, int32_t argc, xt_value *argv) {
|
|
499
|
-
const char *fn = xt_string_data(name);
|
|
500
|
-
double a = xt_to_number(xt_arg_at(argc, argv, 0));
|
|
501
|
-
double b = xt_to_number(xt_arg_at(argc, argv, 1));
|
|
502
|
-
if (!fn) return xt_number(NAN);
|
|
503
|
-
if (strcmp(fn, "abs") == 0) return xt_number(fabs(a));
|
|
504
|
-
if (strcmp(fn, "floor") == 0) return xt_number(floor(a));
|
|
505
|
-
if (strcmp(fn, "ceil") == 0) return xt_number(ceil(a));
|
|
506
|
-
if (strcmp(fn, "round") == 0) return xt_number(floor(a + 0.5));
|
|
507
|
-
if (strcmp(fn, "trunc") == 0) return xt_number(trunc(a));
|
|
508
|
-
if (strcmp(fn, "sqrt") == 0) return xt_number(sqrt(a));
|
|
509
|
-
if (strcmp(fn, "cbrt") == 0) return xt_number(cbrt(a));
|
|
510
|
-
if (strcmp(fn, "pow") == 0) return xt_number(pow(a, b));
|
|
511
|
-
if (strcmp(fn, "exp") == 0) return xt_number(exp(a));
|
|
512
|
-
if (strcmp(fn, "log") == 0) return xt_number(log(a));
|
|
513
|
-
if (strcmp(fn, "log2") == 0) return xt_number(log2(a));
|
|
514
|
-
if (strcmp(fn, "log10") == 0) return xt_number(log10(a));
|
|
515
|
-
if (strcmp(fn, "log1p") == 0) return xt_number(log1p(a));
|
|
516
|
-
if (strcmp(fn, "expm1") == 0) return xt_number(expm1(a));
|
|
517
|
-
if (strcmp(fn, "sinh") == 0) return xt_number(sinh(a));
|
|
518
|
-
if (strcmp(fn, "cosh") == 0) return xt_number(cosh(a));
|
|
519
|
-
if (strcmp(fn, "tanh") == 0) return xt_number(tanh(a));
|
|
520
|
-
if (strcmp(fn, "asinh") == 0) return xt_number(asinh(a));
|
|
521
|
-
if (strcmp(fn, "acosh") == 0) return xt_number(acosh(a));
|
|
522
|
-
if (strcmp(fn, "atanh") == 0) return xt_number(atanh(a));
|
|
523
|
-
if (strcmp(fn, "fround") == 0) return xt_number((double)(float)a);
|
|
524
|
-
if (strcmp(fn, "imul") == 0) return xt_number((double)((int32_t)xt_to_int32(xt_arg_at(argc, argv, 0)) * (int32_t)xt_to_int32(xt_arg_at(argc, argv, 1))));
|
|
525
|
-
if (strcmp(fn, "clz32") == 0) {
|
|
526
|
-
uint32_t v = (uint32_t)xt_to_int32(xt_arg_at(argc, argv, 0));
|
|
527
|
-
int count = 0;
|
|
528
|
-
if (v == 0) count = 32;
|
|
529
|
-
else { while (!(v & 0x80000000u)) { v <<= 1; count++; } }
|
|
530
|
-
return xt_number((double)count);
|
|
531
|
-
}
|
|
532
|
-
if (strcmp(fn, "sin") == 0) return xt_number(sin(a));
|
|
533
|
-
if (strcmp(fn, "cos") == 0) return xt_number(cos(a));
|
|
534
|
-
if (strcmp(fn, "tan") == 0) return xt_number(tan(a));
|
|
535
|
-
if (strcmp(fn, "asin") == 0) return xt_number(asin(a));
|
|
536
|
-
if (strcmp(fn, "acos") == 0) return xt_number(acos(a));
|
|
537
|
-
if (strcmp(fn, "atan") == 0) return xt_number(atan(a));
|
|
538
|
-
if (strcmp(fn, "atan2") == 0) return xt_number(atan2(a, b));
|
|
539
|
-
if (strcmp(fn, "hypot") == 0) return xt_number(hypot(a, b));
|
|
540
|
-
if (strcmp(fn, "sign") == 0) {
|
|
541
|
-
if (isnan(a)) return xt_number(NAN);
|
|
542
|
-
return xt_number(a > 0 ? 1.0 : a < 0 ? -1.0 : a);
|
|
543
|
-
}
|
|
544
|
-
if (strcmp(fn, "random") == 0) return xt_number((double)rand() / ((double)RAND_MAX + 1.0));
|
|
545
|
-
if (strcmp(fn, "min") == 0) {
|
|
546
|
-
double result = INFINITY;
|
|
547
|
-
for (int32_t i = 0; i < argc; i++) {
|
|
548
|
-
double v = xt_to_number(argv[i]);
|
|
549
|
-
if (isnan(v)) return xt_number(NAN);
|
|
550
|
-
if (v < result) result = v;
|
|
551
|
-
}
|
|
552
|
-
return xt_number(result);
|
|
553
|
-
}
|
|
554
|
-
if (strcmp(fn, "max") == 0) {
|
|
555
|
-
double result = -INFINITY;
|
|
556
|
-
for (int32_t i = 0; i < argc; i++) {
|
|
557
|
-
double v = xt_to_number(argv[i]);
|
|
558
|
-
if (isnan(v)) return xt_number(NAN);
|
|
559
|
-
if (v > result) result = v;
|
|
560
|
-
}
|
|
561
|
-
return xt_number(result);
|
|
562
|
-
}
|
|
563
|
-
return xt_number(NAN);
|
|
564
|
-
}
|
|
16
|
+
/*
|
|
17
|
+
* The implementation is grouped by functional area under `xt_stdlib/` and
|
|
18
|
+
* `#include`d here as a single translation unit so the helpers stay `static`
|
|
19
|
+
* while each file stays focused on one area.
|
|
20
|
+
*/
|
|
565
21
|
|
|
22
|
+
#include "xt_stdlib/helpers.inc"
|
|
23
|
+
#include "xt_stdlib/arrays.inc"
|
|
24
|
+
#include "xt_stdlib/strings.inc"
|
|
25
|
+
#include "xt_stdlib/dispatch.inc"
|
|
26
|
+
#include "xt_stdlib/math.inc"
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/* -- Array statics -------------------------------------------------------- */
|
|
2
|
+
|
|
3
|
+
xt_value xt_array_static(xt_value name, int32_t argc, xt_value *argv) {
|
|
4
|
+
const char *fn = xt_string_data(name);
|
|
5
|
+
if (!fn) return XT_UNDEFINED;
|
|
6
|
+
if (strcmp(fn, "isArray") == 0) return xt_bool(XT_IS_ARRAY(xt_arg_at(argc, argv, 0)));
|
|
7
|
+
if (strcmp(fn, "of") == 0) return xt_array_new(argc, argv);
|
|
8
|
+
if (strcmp(fn, "from") == 0) {
|
|
9
|
+
xt_value source = xt_arg_at(argc, argv, 0);
|
|
10
|
+
xt_value mapper = xt_arg_at(argc, argv, 1);
|
|
11
|
+
xt_value out = xt_array_new(0, NULL);
|
|
12
|
+
if (XT_IS_ARRAY(source)) {
|
|
13
|
+
xt_array *array = xt_as_array(source);
|
|
14
|
+
for (uint32_t i = 0; i < array->length; i++) {
|
|
15
|
+
xt_value item = array->items[i];
|
|
16
|
+
if (XT_IS_FUNCTION(mapper)) { xt_value args[2] = {item, xt_number((double)i)}; item = xt_closure_call(mapper, 2, args); }
|
|
17
|
+
xt_array_push(out, item);
|
|
18
|
+
}
|
|
19
|
+
} else if (XT_IS_STRING(source)) {
|
|
20
|
+
xt_string *s = xt_as_string(source);
|
|
21
|
+
for (uint32_t i = 0; i < s->length; i++) {
|
|
22
|
+
xt_value item = xt_string_new(s->data + i, 1);
|
|
23
|
+
if (XT_IS_FUNCTION(mapper)) { xt_value args[2] = {item, xt_number((double)i)}; item = xt_closure_call(mapper, 2, args); }
|
|
24
|
+
xt_array_push(out, item);
|
|
25
|
+
}
|
|
26
|
+
} else {
|
|
27
|
+
double length = xt_to_number(xt_get(source, xt_string_from_cstr("length")));
|
|
28
|
+
for (int32_t i = 0; i < (int32_t)length; i++) {
|
|
29
|
+
xt_value item = xt_get(source, xt_number((double)i));
|
|
30
|
+
if (XT_IS_FUNCTION(mapper)) { xt_value args[2] = {item, xt_number((double)i)}; item = xt_closure_call(mapper, 2, args); }
|
|
31
|
+
xt_array_push(out, item);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
return out;
|
|
35
|
+
}
|
|
36
|
+
return XT_UNDEFINED;
|
|
37
|
+
}
|