xbintsc 0.1.3 → 0.1.8
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 +14 -13
- package/dist/src/ast/common.d.ts +33 -0
- package/dist/src/ast/common.js +7 -0
- package/dist/src/ast/common.js.map +1 -0
- package/dist/src/ast/declarations.d.ts +110 -0
- package/dist/src/ast/declarations.js +5 -0
- package/dist/src/ast/declarations.js.map +1 -0
- package/dist/src/ast/expressions.d.ts +219 -0
- package/dist/src/ast/expressions.js +6 -0
- package/dist/src/ast/expressions.js.map +1 -0
- package/dist/src/ast/kinds.d.ts +160 -0
- package/dist/src/ast/kinds.js +171 -0
- package/dist/src/ast/kinds.js.map +1 -0
- package/dist/src/ast/modules.d.ts +61 -0
- package/dist/src/ast/modules.js +5 -0
- package/dist/src/ast/modules.js.map +1 -0
- package/dist/src/ast/nodes.d.ts +11 -839
- package/dist/src/ast/nodes.js +11 -237
- package/dist/src/ast/nodes.js.map +1 -1
- package/dist/src/ast/operators.d.ts +71 -0
- package/dist/src/ast/operators.js +77 -0
- package/dist/src/ast/operators.js.map +1 -0
- package/dist/src/ast/statements.d.ts +120 -0
- package/dist/src/ast/statements.js +5 -0
- package/dist/src/ast/statements.js.map +1 -0
- package/dist/src/ast/types.d.ts +123 -0
- package/dist/src/ast/types.js +6 -0
- package/dist/src/ast/types.js.map +1 -0
- package/dist/src/codegen/generator/calls.d.ts +22 -0
- package/dist/src/codegen/generator/calls.js +301 -0
- package/dist/src/codegen/generator/calls.js.map +1 -0
- package/dist/src/codegen/generator/context.d.ts +45 -0
- package/dist/src/codegen/generator/context.js +128 -0
- package/dist/src/codegen/generator/context.js.map +1 -0
- package/dist/src/codegen/generator/expressions.d.ts +22 -0
- package/dist/src/codegen/generator/expressions.js +383 -0
- package/dist/src/codegen/generator/expressions.js.map +1 -0
- package/dist/src/codegen/generator/generator.d.ts +22 -0
- package/dist/src/codegen/generator/generator.js +21 -0
- package/dist/src/codegen/generator/generator.js.map +1 -0
- package/dist/src/codegen/generator/module.d.ts +15 -0
- package/dist/src/codegen/generator/module.js +114 -0
- package/dist/src/codegen/generator/module.js.map +1 -0
- package/dist/src/codegen/generator/state.d.ts +40 -0
- package/dist/src/codegen/generator/state.js +84 -0
- package/dist/src/codegen/generator/state.js.map +1 -0
- package/dist/src/codegen/generator/statements.d.ts +22 -0
- package/dist/src/codegen/generator/statements.js +425 -0
- package/dist/src/codegen/generator/statements.js.map +1 -0
- package/dist/src/codegen/generator/tables.d.ts +19 -0
- package/dist/src/codegen/generator/tables.js +153 -0
- package/dist/src/codegen/generator/tables.js.map +1 -0
- package/dist/src/codegen/llvm.d.ts +4 -13
- package/dist/src/codegen/llvm.js +4 -1159
- package/dist/src/codegen/llvm.js.map +1 -1
- package/dist/src/driver/compiler.js +13 -4
- package/dist/src/driver/compiler.js.map +1 -1
- package/dist/src/lexer/char.d.ts +78 -0
- package/dist/src/lexer/char.js +106 -0
- package/dist/src/lexer/char.js.map +1 -0
- package/dist/src/lexer/scanner.js +1 -98
- package/dist/src/lexer/scanner.js.map +1 -1
- package/dist/src/parser/context.d.ts +58 -0
- package/dist/src/parser/context.js +174 -0
- package/dist/src/parser/context.js.map +1 -0
- package/dist/src/parser/declarations.d.ts +26 -0
- package/dist/src/parser/declarations.js +461 -0
- package/dist/src/parser/declarations.js.map +1 -0
- package/dist/src/parser/expressions.d.ts +27 -0
- package/dist/src/parser/expressions.js +437 -0
- package/dist/src/parser/expressions.js.map +1 -0
- package/dist/src/parser/helpers.d.ts +7 -0
- package/dist/src/parser/helpers.js +36 -0
- package/dist/src/parser/helpers.js.map +1 -0
- package/dist/src/parser/literals.d.ts +16 -0
- package/dist/src/parser/literals.js +193 -0
- package/dist/src/parser/literals.js.map +1 -0
- package/dist/src/parser/modules.d.ts +12 -0
- package/dist/src/parser/modules.js +175 -0
- package/dist/src/parser/modules.js.map +1 -0
- package/dist/src/parser/operators.d.ts +12 -0
- package/dist/src/parser/operators.js +172 -0
- package/dist/src/parser/operators.js.map +1 -0
- package/dist/src/parser/parser.d.ts +17 -122
- package/dist/src/parser/parser.js +18 -2307
- package/dist/src/parser/parser.js.map +1 -1
- package/dist/src/parser/speculation.d.ts +6 -0
- package/dist/src/parser/speculation.js +10 -0
- package/dist/src/parser/speculation.js.map +1 -0
- package/dist/src/parser/statements.d.ts +28 -0
- package/dist/src/parser/statements.js +402 -0
- package/dist/src/parser/statements.js.map +1 -0
- package/dist/src/parser/types.d.ts +21 -0
- package/dist/src/parser/types.js +338 -0
- package/dist/src/parser/types.js.map +1 -0
- package/dist/tests/e2e/compile.test.js +122 -2
- package/dist/tests/e2e/compile.test.js.map +1 -1
- package/dist/tests/parser/parser.test.js +9 -1
- package/dist/tests/parser/parser.test.js.map +1 -1
- package/package.json +1 -1
- package/runtime/rt.h +32 -0
- package/runtime/rt_internal.h +106 -0
- package/runtime/xt_alloc.c +38 -0
- package/runtime/xt_builtins.c +192 -0
- package/runtime/xt_containers.c +225 -0
- package/runtime/xt_io.c +133 -0
- package/runtime/xt_stdlib.c +502 -0
- package/runtime/xt_values.c +291 -0
- package/scripts/build-runtime.mjs +8 -1
- package/src/ast/common.ts +210 -0
- package/src/ast/declarations.ts +130 -0
- package/src/ast/expressions.ts +275 -0
- package/src/ast/kinds.ts +176 -0
- package/src/ast/modules.ts +73 -0
- package/src/ast/nodes.ts +11 -1101
- package/src/ast/operators.ts +76 -0
- package/src/ast/statements.ts +148 -0
- package/src/ast/types.ts +173 -0
- package/src/codegen/generator/calls.ts +355 -0
- package/src/codegen/generator/context.ts +156 -0
- package/src/codegen/generator/expressions.ts +431 -0
- package/src/codegen/generator/generator.ts +35 -0
- package/src/codegen/generator/module.ts +139 -0
- package/src/codegen/generator/state.ts +126 -0
- package/src/codegen/generator/statements.ts +474 -0
- package/src/codegen/generator/tables.ts +171 -0
- package/src/codegen/llvm.ts +4 -1305
- package/src/driver/compiler.ts +17 -5
- package/src/lexer/char.ts +116 -0
- package/src/lexer/scanner.ts +9 -109
- package/src/parser/context.ts +196 -0
- package/src/parser/declarations.ts +502 -0
- package/src/parser/expressions.ts +465 -0
- package/src/parser/helpers.ts +42 -0
- package/src/parser/literals.ts +207 -0
- package/src/parser/modules.ts +194 -0
- package/src/parser/operators.ts +181 -0
- package/src/parser/parser.ts +35 -2369
- package/src/parser/speculation.ts +9 -0
- package/src/parser/statements.ts +457 -0
- package/src/parser/types.ts +365 -0
- package/runtime/xt_runtime.c +0 -682
|
@@ -0,0 +1,291 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* xbintsc runtime — values.
|
|
3
|
+
*
|
|
4
|
+
* Constructors, the string representation, JS conversions, arithmetic and
|
|
5
|
+
* comparison operators. All of these operate on the NaN-boxed `xt_value`.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
#include "rt_internal.h"
|
|
9
|
+
|
|
10
|
+
#include <math.h>
|
|
11
|
+
#include <stdio.h>
|
|
12
|
+
#include <stdlib.h>
|
|
13
|
+
#include <string.h>
|
|
14
|
+
|
|
15
|
+
/* ------------------------------------------------------------------------- */
|
|
16
|
+
/* Constructors */
|
|
17
|
+
/* ------------------------------------------------------------------------- */
|
|
18
|
+
|
|
19
|
+
xt_value xt_undefined(void) { return XT_UNDEFINED; }
|
|
20
|
+
xt_value xt_null(void) { return XT_NULL; }
|
|
21
|
+
xt_value xt_bool(int b) { return b ? XT_TRUE : XT_FALSE; }
|
|
22
|
+
xt_value xt_number(double d) { return xt_from_double(d); }
|
|
23
|
+
|
|
24
|
+
xt_string *xt_string_alloc(size_t length) {
|
|
25
|
+
xt_string *s = (xt_string *)xt_alloc(sizeof(xt_string), XT_OBJECT_KIND_STRING);
|
|
26
|
+
s->length = (uint32_t)length;
|
|
27
|
+
s->capacity = (uint32_t)length + 1;
|
|
28
|
+
s->data = (char *)malloc(s->capacity);
|
|
29
|
+
if (!s->data) {
|
|
30
|
+
fprintf(stderr, "xbintsc: out of memory allocating string\n");
|
|
31
|
+
abort();
|
|
32
|
+
}
|
|
33
|
+
s->data[length] = '\0';
|
|
34
|
+
return s;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
xt_value xt_string_new(const char *data, size_t len) {
|
|
38
|
+
xt_string *s = xt_string_alloc(len);
|
|
39
|
+
if (len > 0) memcpy(s->data, data, len);
|
|
40
|
+
return XT_FROM_PTR(XT_TAG_STRING, s);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
xt_value xt_string_from_cstr(const char *data) { return xt_string_new(data, strlen(data)); }
|
|
44
|
+
|
|
45
|
+
xt_string *xt_as_string(xt_value v);
|
|
46
|
+
|
|
47
|
+
const char *xt_string_data(xt_value value) {
|
|
48
|
+
xt_string *s = xt_as_string(value);
|
|
49
|
+
return s ? s->data : NULL;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
int32_t xt_string_length_value(xt_value value) {
|
|
53
|
+
xt_string *s = xt_as_string(value);
|
|
54
|
+
return s ? (int32_t)s->length : -1;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/* ------------------------------------------------------------------------- */
|
|
58
|
+
/* Strings */
|
|
59
|
+
/* ------------------------------------------------------------------------- */
|
|
60
|
+
|
|
61
|
+
xt_string *xt_as_string(xt_value v) {
|
|
62
|
+
if (XT_IS_STRING(v)) return (xt_string *)XT_GET_PTR(v);
|
|
63
|
+
return NULL;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
int32_t xt_string_length(xt_string *s) { return (int32_t)s->length; }
|
|
67
|
+
|
|
68
|
+
static xt_value xt_string_concat(xt_string *a, xt_string *b) {
|
|
69
|
+
size_t total = (size_t)a->length + (size_t)b->length;
|
|
70
|
+
xt_string *out = xt_string_alloc(total);
|
|
71
|
+
memcpy(out->data, a->data, a->length);
|
|
72
|
+
memcpy(out->data + a->length, b->data, b->length);
|
|
73
|
+
return XT_FROM_PTR(XT_TAG_STRING, out);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
int xt_string_equals(xt_string *a, xt_string *b) {
|
|
77
|
+
return a->length == b->length && memcmp(a->data, b->data, a->length) == 0;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/*
|
|
81
|
+
* Format a double the way JavaScript's ToString does for the common cases:
|
|
82
|
+
* integers print without a decimal point, everything else uses the shortest
|
|
83
|
+
* representation that round-trips.
|
|
84
|
+
*/
|
|
85
|
+
static void xt_format_double(double d, char *buffer, size_t size) {
|
|
86
|
+
if (isnan(d)) {
|
|
87
|
+
snprintf(buffer, size, "NaN");
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
if (isinf(d)) {
|
|
91
|
+
snprintf(buffer, size, d < 0 ? "-Infinity" : "Infinity");
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
if (d == 0.0) {
|
|
95
|
+
snprintf(buffer, size, "0");
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
if (d == floor(d) && fabs(d) < 1e21) {
|
|
99
|
+
snprintf(buffer, size, "%.0f", d);
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
for (int precision = 1; precision <= 17; precision++) {
|
|
103
|
+
snprintf(buffer, size, "%.*g", precision, d);
|
|
104
|
+
if (strtod(buffer, NULL) == d) return;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/* ------------------------------------------------------------------------- */
|
|
109
|
+
/* Conversions */
|
|
110
|
+
/* ------------------------------------------------------------------------- */
|
|
111
|
+
|
|
112
|
+
int xt_truthy(xt_value v) {
|
|
113
|
+
if (XT_IS_NUMBER(v)) {
|
|
114
|
+
double d = xt_to_double(v);
|
|
115
|
+
return d != 0.0 && !isnan(d);
|
|
116
|
+
}
|
|
117
|
+
if (v == XT_UNDEFINED || v == XT_NULL) return 0;
|
|
118
|
+
if (v == XT_FALSE) return 0;
|
|
119
|
+
if (v == XT_TRUE) return 1;
|
|
120
|
+
return 1; /* objects, arrays, functions and non-empty strings are truthy */
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
double xt_to_number(xt_value v) {
|
|
124
|
+
if (XT_IS_NUMBER(v)) return xt_to_double(v);
|
|
125
|
+
if (v == XT_TRUE) return 1.0;
|
|
126
|
+
if (v == XT_FALSE) return 0.0;
|
|
127
|
+
if (v == XT_UNDEFINED) return NAN;
|
|
128
|
+
if (v == XT_NULL) return 0.0;
|
|
129
|
+
if (XT_IS_STRING(v)) {
|
|
130
|
+
xt_string *s = xt_as_string(v);
|
|
131
|
+
if (s->length == 0) return 0.0;
|
|
132
|
+
char *end = NULL;
|
|
133
|
+
double parsed = strtod(s->data, &end);
|
|
134
|
+
if (end != s->data + s->length) return NAN;
|
|
135
|
+
return parsed;
|
|
136
|
+
}
|
|
137
|
+
return NAN;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
static xt_value xt_number_to_string_value(double d) {
|
|
141
|
+
char buffer[64];
|
|
142
|
+
xt_format_double(d, buffer, sizeof(buffer));
|
|
143
|
+
return xt_string_from_cstr(buffer);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
xt_value xt_to_string(xt_value v) {
|
|
147
|
+
if (XT_IS_STRING(v)) return v;
|
|
148
|
+
if (XT_IS_NUMBER(v)) return xt_number_to_string_value(xt_to_double(v));
|
|
149
|
+
if (v == XT_UNDEFINED) return xt_string_from_cstr("undefined");
|
|
150
|
+
if (v == XT_NULL) return xt_string_from_cstr("null");
|
|
151
|
+
if (v == XT_TRUE) return xt_string_from_cstr("true");
|
|
152
|
+
if (v == XT_FALSE) return xt_string_from_cstr("false");
|
|
153
|
+
if (XT_IS_ARRAY(v)) {
|
|
154
|
+
xt_array *a = (xt_array *)XT_GET_PTR(v);
|
|
155
|
+
/* Join elements with commas, like Array.prototype.toString. */
|
|
156
|
+
size_t capacity = 32;
|
|
157
|
+
char *out = (char *)malloc(capacity);
|
|
158
|
+
size_t length = 0;
|
|
159
|
+
out[0] = '\0';
|
|
160
|
+
for (uint32_t i = 0; i < a->length; i++) {
|
|
161
|
+
xt_value s = xt_to_string(a->items[i]);
|
|
162
|
+
xt_string *str = xt_as_string(s);
|
|
163
|
+
if (length + str->length + 2 > capacity) {
|
|
164
|
+
capacity = (length + str->length + 2) * 2;
|
|
165
|
+
out = (char *)realloc(out, capacity);
|
|
166
|
+
}
|
|
167
|
+
if (i > 0) out[length++] = ',';
|
|
168
|
+
memcpy(out + length, str->data, str->length);
|
|
169
|
+
length += str->length;
|
|
170
|
+
out[length] = '\0';
|
|
171
|
+
}
|
|
172
|
+
xt_value result = xt_string_new(out, length);
|
|
173
|
+
free(out);
|
|
174
|
+
return result;
|
|
175
|
+
}
|
|
176
|
+
if (XT_IS_FUNCTION(v)) return xt_string_from_cstr("function () { [native code] }");
|
|
177
|
+
return xt_string_from_cstr("[object Object]");
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
xt_value xt_typeof(xt_value v) {
|
|
181
|
+
if (XT_IS_NUMBER(v)) return xt_string_from_cstr("number");
|
|
182
|
+
if (XT_IS_STRING(v)) return xt_string_from_cstr("string");
|
|
183
|
+
if (v == XT_TRUE || v == XT_FALSE) return xt_string_from_cstr("boolean");
|
|
184
|
+
if (v == XT_UNDEFINED) return xt_string_from_cstr("undefined");
|
|
185
|
+
if (XT_IS_FUNCTION(v)) return xt_string_from_cstr("function");
|
|
186
|
+
if (v == XT_NULL) return xt_string_from_cstr("object");
|
|
187
|
+
return xt_string_from_cstr("object");
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
/* ------------------------------------------------------------------------- */
|
|
191
|
+
/* Arithmetic */
|
|
192
|
+
/* ------------------------------------------------------------------------- */
|
|
193
|
+
|
|
194
|
+
xt_value xt_add(xt_value a, xt_value b) {
|
|
195
|
+
if (XT_IS_NUMBER(a) && XT_IS_NUMBER(b)) {
|
|
196
|
+
return xt_number(xt_to_double(a) + xt_to_double(b));
|
|
197
|
+
}
|
|
198
|
+
/* JavaScript's `+` concatenates when either operand is a string. */
|
|
199
|
+
if (XT_IS_STRING(a) || XT_IS_STRING(b)) {
|
|
200
|
+
xt_value sa = xt_to_string(a);
|
|
201
|
+
xt_value sb = xt_to_string(b);
|
|
202
|
+
return xt_string_concat(xt_as_string(sa), xt_as_string(sb));
|
|
203
|
+
}
|
|
204
|
+
return xt_number(xt_to_number(a) + xt_to_number(b));
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
xt_value xt_sub(xt_value a, xt_value b) { return xt_number(xt_to_number(a) - xt_to_number(b)); }
|
|
208
|
+
xt_value xt_mul(xt_value a, xt_value b) { return xt_number(xt_to_number(a) * xt_to_number(b)); }
|
|
209
|
+
xt_value xt_div(xt_value a, xt_value b) { return xt_number(xt_to_number(a) / xt_to_number(b)); }
|
|
210
|
+
|
|
211
|
+
xt_value xt_mod(xt_value a, xt_value b) {
|
|
212
|
+
double x = xt_to_number(a);
|
|
213
|
+
double y = xt_to_number(b);
|
|
214
|
+
return xt_number(fmod(x, y));
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
xt_value xt_pow(xt_value a, xt_value b) { return xt_number(pow(xt_to_number(a), xt_to_number(b))); }
|
|
218
|
+
xt_value xt_neg(xt_value a) { return xt_number(-xt_to_number(a)); }
|
|
219
|
+
xt_value xt_pos(xt_value a) { return xt_number(xt_to_number(a)); }
|
|
220
|
+
|
|
221
|
+
int32_t xt_to_int32(xt_value v) {
|
|
222
|
+
double d = xt_to_number(v);
|
|
223
|
+
if (isnan(d) || isinf(d)) return 0;
|
|
224
|
+
return (int32_t)(uint32_t)(int64_t)d;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
xt_value xt_bit_and(xt_value a, xt_value b) { return xt_number((double)(xt_to_int32(a) & xt_to_int32(b))); }
|
|
228
|
+
xt_value xt_bit_or(xt_value a, xt_value b) { return xt_number((double)(xt_to_int32(a) | xt_to_int32(b))); }
|
|
229
|
+
xt_value xt_bit_xor(xt_value a, xt_value b) { return xt_number((double)(xt_to_int32(a) ^ xt_to_int32(b))); }
|
|
230
|
+
xt_value xt_bit_not(xt_value a) { return xt_number((double)(~xt_to_int32(a))); }
|
|
231
|
+
xt_value xt_shl(xt_value a, xt_value b) { return xt_number((double)(int32_t)((uint32_t)xt_to_int32(a) << (xt_to_int32(b) & 31))); }
|
|
232
|
+
xt_value xt_shr(xt_value a, xt_value b) { return xt_number((double)(xt_to_int32(a) >> (xt_to_int32(b) & 31))); }
|
|
233
|
+
xt_value xt_ushr(xt_value a, xt_value b) {
|
|
234
|
+
return xt_number((double)(uint32_t)((uint32_t)xt_to_int32(a) >> (xt_to_int32(b) & 31)));
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
/* ------------------------------------------------------------------------- */
|
|
238
|
+
/* Comparison */
|
|
239
|
+
/* ------------------------------------------------------------------------- */
|
|
240
|
+
|
|
241
|
+
xt_value xt_lt(xt_value a, xt_value b) {
|
|
242
|
+
if (XT_IS_STRING(a) && XT_IS_STRING(b)) {
|
|
243
|
+
xt_string *x = xt_as_string(a);
|
|
244
|
+
xt_string *y = xt_as_string(b);
|
|
245
|
+
size_t n = x->length < y->length ? x->length : y->length;
|
|
246
|
+
int cmp = memcmp(x->data, y->data, n);
|
|
247
|
+
if (cmp == 0) return xt_bool(x->length < y->length);
|
|
248
|
+
return xt_bool(cmp < 0);
|
|
249
|
+
}
|
|
250
|
+
return xt_bool(xt_to_number(a) < xt_to_number(b));
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
xt_value xt_le(xt_value a, xt_value b) {
|
|
254
|
+
if (XT_IS_STRING(a) && XT_IS_STRING(b)) {
|
|
255
|
+
xt_string *x = xt_as_string(a);
|
|
256
|
+
xt_string *y = xt_as_string(b);
|
|
257
|
+
size_t n = x->length < y->length ? x->length : y->length;
|
|
258
|
+
int cmp = memcmp(x->data, y->data, n);
|
|
259
|
+
if (cmp == 0) return xt_bool(x->length <= y->length);
|
|
260
|
+
return xt_bool(cmp < 0);
|
|
261
|
+
}
|
|
262
|
+
return xt_bool(xt_to_number(a) <= xt_to_number(b));
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
xt_value xt_gt(xt_value a, xt_value b) { return xt_lt(b, a); }
|
|
266
|
+
xt_value xt_ge(xt_value a, xt_value b) { return xt_le(b, a); }
|
|
267
|
+
|
|
268
|
+
static int xt_loose_equals(xt_value a, xt_value b) {
|
|
269
|
+
if (XT_IS_NUMBER(a) && XT_IS_NUMBER(b)) return xt_to_double(a) == xt_to_double(b);
|
|
270
|
+
if (XT_IS_STRING(a) && XT_IS_STRING(b)) return xt_string_equals(xt_as_string(a), xt_as_string(b));
|
|
271
|
+
if (a == b) return 1;
|
|
272
|
+
if ((a == XT_NULL && b == XT_UNDEFINED) || (a == XT_UNDEFINED && b == XT_NULL)) return 1;
|
|
273
|
+
if (XT_IS_BOOL(a)) return xt_loose_equals(xt_number(xt_to_number(a)), b);
|
|
274
|
+
if (XT_IS_BOOL(b)) return xt_loose_equals(a, xt_number(xt_to_number(b)));
|
|
275
|
+
if (XT_IS_STRING(a) && XT_IS_NUMBER(b)) return xt_to_number(a) == xt_to_double(b);
|
|
276
|
+
if (XT_IS_NUMBER(a) && XT_IS_STRING(b)) return xt_to_double(a) == xt_to_number(b);
|
|
277
|
+
return 0;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
xt_value xt_eq(xt_value a, xt_value b) { return xt_bool(xt_loose_equals(a, b)); }
|
|
281
|
+
xt_value xt_ne(xt_value a, xt_value b) { return xt_bool(!xt_loose_equals(a, b)); }
|
|
282
|
+
|
|
283
|
+
xt_value xt_seq(xt_value a, xt_value b) {
|
|
284
|
+
if (XT_IS_NUMBER(a) && XT_IS_NUMBER(b)) return xt_bool(xt_to_double(a) == xt_to_double(b));
|
|
285
|
+
if (XT_IS_STRING(a) && XT_IS_STRING(b)) return xt_bool(xt_string_equals(xt_as_string(a), xt_as_string(b)));
|
|
286
|
+
return xt_bool(a == b);
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
xt_value xt_sne(xt_value a, xt_value b) { return xt_bool(!xt_truthy(xt_seq(a, b))); }
|
|
290
|
+
xt_value xt_not(xt_value a) { return xt_bool(!xt_truthy(a)); }
|
|
291
|
+
|
|
@@ -18,7 +18,14 @@ mkdirSync(outDir, { recursive: true });
|
|
|
18
18
|
const clang = process.env.xbintsc_CLANG ?? "clang";
|
|
19
19
|
|
|
20
20
|
const sources = [
|
|
21
|
-
|
|
21
|
+
// Core runtime, split into translation units (see runtime/rt_internal.h).
|
|
22
|
+
["xt_alloc.c", "xt_alloc.o"],
|
|
23
|
+
["xt_values.c", "xt_values.o"],
|
|
24
|
+
["xt_containers.c", "xt_containers.o"],
|
|
25
|
+
["xt_stdlib.c", "xt_stdlib.o"],
|
|
26
|
+
["xt_builtins.c", "xt_builtins.o"],
|
|
27
|
+
["xt_io.c", "xt_io.o"],
|
|
28
|
+
// Node extension sources.
|
|
22
29
|
["ext_node/fs/read_file.c", "ext_node_fs_read_file.o"],
|
|
23
30
|
];
|
|
24
31
|
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Core AST shapes shared by every node category: source ranges, the base
|
|
3
|
+
* `Node` interface, the `Modifier` node and the `Expression`/`Statement`/
|
|
4
|
+
* `TypeNode` discriminated unions.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { SyntaxKind, type ModifierKind } from "./kinds.js";
|
|
8
|
+
import type {
|
|
9
|
+
ArrayLiteralExpression,
|
|
10
|
+
ArrowFunction,
|
|
11
|
+
AsExpression,
|
|
12
|
+
AwaitExpression,
|
|
13
|
+
BigIntLiteral,
|
|
14
|
+
BinaryExpression,
|
|
15
|
+
BooleanLiteral,
|
|
16
|
+
CallExpression,
|
|
17
|
+
ClassExpression,
|
|
18
|
+
ConditionalExpression,
|
|
19
|
+
DeleteExpression,
|
|
20
|
+
ElementAccessExpression,
|
|
21
|
+
FunctionExpression,
|
|
22
|
+
Identifier,
|
|
23
|
+
NewExpression,
|
|
24
|
+
NoSubstitutionTemplateLiteral,
|
|
25
|
+
NonNullExpression,
|
|
26
|
+
NullLiteral,
|
|
27
|
+
NumericLiteral,
|
|
28
|
+
ObjectLiteralExpression,
|
|
29
|
+
ParenthesizedExpression,
|
|
30
|
+
PostfixUnaryExpression,
|
|
31
|
+
PrefixUnaryExpression,
|
|
32
|
+
PrivateIdentifier,
|
|
33
|
+
PropertyAccessExpression,
|
|
34
|
+
RegularExpressionLiteral,
|
|
35
|
+
SatisfiesExpression,
|
|
36
|
+
SpreadElement,
|
|
37
|
+
StringLiteral,
|
|
38
|
+
TaggedTemplateExpression,
|
|
39
|
+
TemplateLiteral,
|
|
40
|
+
ThisExpression,
|
|
41
|
+
TypeOfExpression,
|
|
42
|
+
UndefinedLiteral,
|
|
43
|
+
VoidExpression,
|
|
44
|
+
YieldExpression,
|
|
45
|
+
} from "./expressions.js";
|
|
46
|
+
import type {
|
|
47
|
+
Block,
|
|
48
|
+
BreakStatement,
|
|
49
|
+
ContinueStatement,
|
|
50
|
+
DebuggerStatement,
|
|
51
|
+
DoStatement,
|
|
52
|
+
EmptyStatement,
|
|
53
|
+
ExpressionStatement,
|
|
54
|
+
ForInStatement,
|
|
55
|
+
ForOfStatement,
|
|
56
|
+
ForStatement,
|
|
57
|
+
IfStatement,
|
|
58
|
+
LabeledStatement,
|
|
59
|
+
ReturnStatement,
|
|
60
|
+
SwitchStatement,
|
|
61
|
+
ThrowStatement,
|
|
62
|
+
TryStatement,
|
|
63
|
+
VariableStatement,
|
|
64
|
+
WhileStatement,
|
|
65
|
+
} from "./statements.js";
|
|
66
|
+
import type {
|
|
67
|
+
ClassDeclaration,
|
|
68
|
+
EnumDeclaration,
|
|
69
|
+
FunctionDeclaration,
|
|
70
|
+
InterfaceDeclaration,
|
|
71
|
+
ModuleDeclaration,
|
|
72
|
+
TypeAliasDeclaration,
|
|
73
|
+
} from "./declarations.js";
|
|
74
|
+
import type {
|
|
75
|
+
ExportAssignment,
|
|
76
|
+
ExportDeclaration,
|
|
77
|
+
ImportDeclaration,
|
|
78
|
+
} from "./modules.js";
|
|
79
|
+
import type {
|
|
80
|
+
ArrayTypeNode,
|
|
81
|
+
ConditionalTypeNode,
|
|
82
|
+
FunctionTypeNode,
|
|
83
|
+
IndexedAccessTypeNode,
|
|
84
|
+
InferTypeNode,
|
|
85
|
+
IntersectionTypeNode,
|
|
86
|
+
KeywordTypeNode,
|
|
87
|
+
LiteralTypeNode,
|
|
88
|
+
MappedTypeNode,
|
|
89
|
+
OptionalTypeNode,
|
|
90
|
+
ParenthesizedTypeNode,
|
|
91
|
+
RestTypeNode,
|
|
92
|
+
TupleTypeNode,
|
|
93
|
+
TypeLiteralNode,
|
|
94
|
+
TypeOperatorNode,
|
|
95
|
+
TypePredicate,
|
|
96
|
+
TypeQueryNode,
|
|
97
|
+
TypeReference,
|
|
98
|
+
UnionTypeNode,
|
|
99
|
+
} from "./types.js";
|
|
100
|
+
|
|
101
|
+
export interface Range {
|
|
102
|
+
/** Inclusive start offset (UTF-16 code units). */
|
|
103
|
+
readonly start: number;
|
|
104
|
+
/** Exclusive end offset. */
|
|
105
|
+
readonly end: number;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
export interface Node extends Range {
|
|
109
|
+
readonly kind: SyntaxKind;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
export interface Modifier extends Node {
|
|
113
|
+
readonly kind: SyntaxKind.Unknown;
|
|
114
|
+
readonly modifierKind: ModifierKind;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
export type Expression =
|
|
118
|
+
| Identifier
|
|
119
|
+
| PrivateIdentifier
|
|
120
|
+
| NumericLiteral
|
|
121
|
+
| BigIntLiteral
|
|
122
|
+
| StringLiteral
|
|
123
|
+
| NoSubstitutionTemplateLiteral
|
|
124
|
+
| TemplateLiteral
|
|
125
|
+
| RegularExpressionLiteral
|
|
126
|
+
| BooleanLiteral
|
|
127
|
+
| NullLiteral
|
|
128
|
+
| UndefinedLiteral
|
|
129
|
+
| ThisExpression
|
|
130
|
+
| ArrayLiteralExpression
|
|
131
|
+
| ObjectLiteralExpression
|
|
132
|
+
| FunctionExpression
|
|
133
|
+
| ArrowFunction
|
|
134
|
+
| ClassExpression
|
|
135
|
+
| CallExpression
|
|
136
|
+
| NewExpression
|
|
137
|
+
| PropertyAccessExpression
|
|
138
|
+
| ElementAccessExpression
|
|
139
|
+
| ParenthesizedExpression
|
|
140
|
+
| PrefixUnaryExpression
|
|
141
|
+
| PostfixUnaryExpression
|
|
142
|
+
| BinaryExpression
|
|
143
|
+
| ConditionalExpression
|
|
144
|
+
| AsExpression
|
|
145
|
+
| SatisfiesExpression
|
|
146
|
+
| NonNullExpression
|
|
147
|
+
| TypeOfExpression
|
|
148
|
+
| VoidExpression
|
|
149
|
+
| DeleteExpression
|
|
150
|
+
| AwaitExpression
|
|
151
|
+
| YieldExpression
|
|
152
|
+
| TaggedTemplateExpression
|
|
153
|
+
| SpreadElement;
|
|
154
|
+
|
|
155
|
+
export type Statement =
|
|
156
|
+
| ExpressionStatement
|
|
157
|
+
| Block
|
|
158
|
+
| EmptyStatement
|
|
159
|
+
| DebuggerStatement
|
|
160
|
+
| VariableStatement
|
|
161
|
+
| IfStatement
|
|
162
|
+
| WhileStatement
|
|
163
|
+
| DoStatement
|
|
164
|
+
| ForStatement
|
|
165
|
+
| ForOfStatement
|
|
166
|
+
| ForInStatement
|
|
167
|
+
| ReturnStatement
|
|
168
|
+
| BreakStatement
|
|
169
|
+
| ContinueStatement
|
|
170
|
+
| ThrowStatement
|
|
171
|
+
| TryStatement
|
|
172
|
+
| SwitchStatement
|
|
173
|
+
| LabeledStatement
|
|
174
|
+
| FunctionDeclaration
|
|
175
|
+
| ClassDeclaration
|
|
176
|
+
| InterfaceDeclaration
|
|
177
|
+
| TypeAliasDeclaration
|
|
178
|
+
| EnumDeclaration
|
|
179
|
+
| ModuleDeclaration
|
|
180
|
+
| ImportDeclaration
|
|
181
|
+
| ExportDeclaration
|
|
182
|
+
| ExportAssignment;
|
|
183
|
+
|
|
184
|
+
export type TypeNode =
|
|
185
|
+
| TypeReference
|
|
186
|
+
| TypePredicate
|
|
187
|
+
| KeywordTypeNode
|
|
188
|
+
| LiteralTypeNode
|
|
189
|
+
| ArrayTypeNode
|
|
190
|
+
| TupleTypeNode
|
|
191
|
+
| UnionTypeNode
|
|
192
|
+
| IntersectionTypeNode
|
|
193
|
+
| FunctionTypeNode
|
|
194
|
+
| TypeLiteralNode
|
|
195
|
+
| ParenthesizedTypeNode
|
|
196
|
+
| TypeQueryNode
|
|
197
|
+
| IndexedAccessTypeNode
|
|
198
|
+
| TypeOperatorNode
|
|
199
|
+
| MappedTypeNode
|
|
200
|
+
| ConditionalTypeNode
|
|
201
|
+
| InferTypeNode
|
|
202
|
+
| OptionalTypeNode
|
|
203
|
+
| RestTypeNode;
|
|
204
|
+
|
|
205
|
+
export interface SourceFileNode extends Node {
|
|
206
|
+
readonly kind: SyntaxKind.SourceFile;
|
|
207
|
+
readonly statements: Statement[];
|
|
208
|
+
readonly fileName: string;
|
|
209
|
+
readonly text: string;
|
|
210
|
+
}
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Declaration nodes of the xbintsc AST (functions, classes, interfaces, ...).
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { NodeFlags, SyntaxKind } from "./kinds.js";
|
|
6
|
+
import type { Expression, Modifier, Node, TypeNode } from "./common.js";
|
|
7
|
+
import type { Identifier, PropertyName, StringLiteral } from "./expressions.js";
|
|
8
|
+
import type { Block } from "./statements.js";
|
|
9
|
+
import type { TypeElement } from "./types.js";
|
|
10
|
+
|
|
11
|
+
// ---------------------------------------------------------------------------
|
|
12
|
+
// Declarations
|
|
13
|
+
// ---------------------------------------------------------------------------
|
|
14
|
+
|
|
15
|
+
export interface Parameter extends Node {
|
|
16
|
+
readonly kind: SyntaxKind.Parameter;
|
|
17
|
+
readonly name: Identifier;
|
|
18
|
+
readonly modifiers: Modifier[];
|
|
19
|
+
readonly dotDotDotToken: boolean;
|
|
20
|
+
readonly questionToken: boolean;
|
|
21
|
+
readonly type?: TypeNode;
|
|
22
|
+
readonly initializer?: Expression;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export interface TypeParameterDeclaration extends Node {
|
|
26
|
+
readonly kind: SyntaxKind.TypeParameterDeclaration;
|
|
27
|
+
readonly name: Identifier;
|
|
28
|
+
readonly constraint?: TypeNode;
|
|
29
|
+
readonly default?: TypeNode;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export interface FunctionDeclaration extends Node {
|
|
33
|
+
readonly kind: SyntaxKind.FunctionDeclaration;
|
|
34
|
+
readonly name?: Identifier;
|
|
35
|
+
readonly modifiers: Modifier[];
|
|
36
|
+
readonly typeParameters: TypeParameterDeclaration[];
|
|
37
|
+
readonly parameters: Parameter[];
|
|
38
|
+
readonly returnType?: TypeNode;
|
|
39
|
+
readonly body?: Block;
|
|
40
|
+
readonly flags: NodeFlags;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export interface HeritageClause extends Node {
|
|
44
|
+
readonly kind: SyntaxKind.HeritageClause;
|
|
45
|
+
readonly token: "extends" | "implements";
|
|
46
|
+
readonly types: ExpressionWithTypeArguments[];
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export interface ExpressionWithTypeArguments extends Node {
|
|
50
|
+
readonly kind: SyntaxKind.ExpressionWithTypeArguments;
|
|
51
|
+
readonly expression: Expression;
|
|
52
|
+
readonly typeArguments: TypeNode[];
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export type ClassElement = PropertyDeclaration | MethodDeclaration | ConstructorDeclaration;
|
|
56
|
+
|
|
57
|
+
export interface PropertyDeclaration extends Node {
|
|
58
|
+
readonly kind: SyntaxKind.PropertyDeclaration;
|
|
59
|
+
readonly name: PropertyName;
|
|
60
|
+
readonly modifiers: Modifier[];
|
|
61
|
+
readonly questionToken: boolean;
|
|
62
|
+
readonly exclamationToken: boolean;
|
|
63
|
+
readonly type?: TypeNode;
|
|
64
|
+
readonly initializer?: Expression;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export interface MethodDeclaration extends Node {
|
|
68
|
+
readonly kind: SyntaxKind.MethodDeclaration;
|
|
69
|
+
readonly name: PropertyName;
|
|
70
|
+
readonly modifiers: Modifier[];
|
|
71
|
+
readonly typeParameters: TypeParameterDeclaration[];
|
|
72
|
+
readonly parameters: Parameter[];
|
|
73
|
+
readonly returnType?: TypeNode;
|
|
74
|
+
readonly body?: Block;
|
|
75
|
+
readonly flags: NodeFlags;
|
|
76
|
+
readonly optional: boolean;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export interface ConstructorDeclaration extends Node {
|
|
80
|
+
readonly kind: SyntaxKind.ConstructorDeclaration;
|
|
81
|
+
readonly modifiers: Modifier[];
|
|
82
|
+
readonly parameters: Parameter[];
|
|
83
|
+
readonly body?: Block;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
export interface ClassDeclaration extends Node {
|
|
87
|
+
readonly kind: SyntaxKind.ClassDeclaration;
|
|
88
|
+
readonly name?: Identifier;
|
|
89
|
+
readonly modifiers: Modifier[];
|
|
90
|
+
readonly typeParameters: TypeParameterDeclaration[];
|
|
91
|
+
readonly heritage: HeritageClause[];
|
|
92
|
+
readonly members: ClassElement[];
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
export interface InterfaceDeclaration extends Node {
|
|
96
|
+
readonly kind: SyntaxKind.InterfaceDeclaration;
|
|
97
|
+
readonly name: Identifier;
|
|
98
|
+
readonly modifiers: Modifier[];
|
|
99
|
+
readonly typeParameters: TypeParameterDeclaration[];
|
|
100
|
+
readonly heritage: HeritageClause[];
|
|
101
|
+
readonly members: TypeElement[];
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
export interface TypeAliasDeclaration extends Node {
|
|
105
|
+
readonly kind: SyntaxKind.TypeAliasDeclaration;
|
|
106
|
+
readonly name: Identifier;
|
|
107
|
+
readonly modifiers: Modifier[];
|
|
108
|
+
readonly typeParameters: TypeParameterDeclaration[];
|
|
109
|
+
readonly type: TypeNode;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
export interface EnumMember extends Node {
|
|
113
|
+
readonly kind: SyntaxKind.EnumMember;
|
|
114
|
+
readonly name: PropertyName;
|
|
115
|
+
readonly initializer?: Expression;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
export interface EnumDeclaration extends Node {
|
|
119
|
+
readonly kind: SyntaxKind.EnumDeclaration;
|
|
120
|
+
readonly name: Identifier;
|
|
121
|
+
readonly modifiers: Modifier[];
|
|
122
|
+
readonly members: EnumMember[];
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
export interface ModuleDeclaration extends Node {
|
|
126
|
+
readonly kind: SyntaxKind.ModuleDeclaration;
|
|
127
|
+
readonly name: Identifier | StringLiteral;
|
|
128
|
+
readonly modifiers: Modifier[];
|
|
129
|
+
readonly body?: Block;
|
|
130
|
+
}
|