feat: multi-instance closures, richer stdlib, and Rust-style diagnostics

Introduce fat function pointers (BuxFn {code, env}) so capturing closures
are heap-allocated per value in both bootstrap and selfhost. Expand
Array/Map/Set/String/Test/Result APIs, add proper tuple codegen and
error snippets with multi-char underlines, golden diagnostic tests, and
LSP diagnostics via buxc check.
This commit is contained in:
2026-07-15 16:00:21 +03:00
parent 94e6806dda
commit 61ac06ab5f
48 changed files with 2789 additions and 362 deletions
+67
View File
@@ -143,6 +143,64 @@ int64_t bux_mod_i64(int64_t a, int64_t b) {
return a % b;
}
/* Integer overflow checks (debug mode) */
int64_t bux_add_i64_checked(int64_t a, int64_t b) {
#if defined(__GNUC__) || defined(__clang__)
int64_t result;
if (__builtin_add_overflow(a, b, &result)) {
bux_panic("integer overflow in addition");
}
return result;
#else
if ((b > 0 && a > INT64_MAX - b) || (b < 0 && a < INT64_MIN - b)) {
bux_panic("integer overflow in addition");
}
return a + b;
#endif
}
int64_t bux_sub_i64_checked(int64_t a, int64_t b) {
#if defined(__GNUC__) || defined(__clang__)
int64_t result;
if (__builtin_sub_overflow(a, b, &result)) {
bux_panic("integer overflow in subtraction");
}
return result;
#else
if ((b > 0 && a < INT64_MIN + b) || (b < 0 && a > INT64_MAX + b)) {
bux_panic("integer overflow in subtraction");
}
return a - b;
#endif
}
int64_t bux_mul_i64_checked(int64_t a, int64_t b) {
#if defined(__GNUC__) || defined(__clang__)
int64_t result;
if (__builtin_mul_overflow(a, b, &result)) {
bux_panic("integer overflow in multiplication");
}
return result;
#else
if (a != 0 && b != 0) {
if ((a > 0 && b > 0 && a > INT64_MAX / b) ||
(a > 0 && b < 0 && b < INT64_MIN / a) ||
(a < 0 && b > 0 && a < INT64_MIN / b) ||
(a < 0 && b < 0 && a < INT64_MAX / b)) {
bux_panic("integer overflow in multiplication");
}
}
return a * b;
#endif
}
int64_t bux_neg_i64_checked(int64_t a) {
if (a == INT64_MIN) {
bux_panic("integer overflow in negation");
}
return -a;
}
/* String operations */
typedef struct {
const char* data;
@@ -189,6 +247,15 @@ void bux_bounds_check(size_t index, size_t len) {
}
}
/* Bounds check that returns the index (usable in expressions) */
size_t bux_index_check(size_t index, size_t len) {
if (index >= len) {
fprintf(stderr, "bux panic: index out of bounds (index %zu, len %zu)\n", index, len);
abort();
}
return index;
}
/* String wrappers with Bux-compatible signatures */
unsigned int bux_strlen(const char* s) {
return (unsigned int)strlen(s);