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
+54
View File
@@ -0,0 +1,54 @@
#!/usr/bin/env bash
# Golden tests for Rust-style compiler diagnostics.
# Usage: from repo root: tests/error_golden/run.sh [path/to/buxc]
set -euo pipefail
ROOT="$(cd "$(dirname "$0")/../.." && pwd)"
BUXC="${1:-$ROOT/buxc}"
DIR="$(cd "$(dirname "$0")" && pwd)"
if [[ ! -x "$BUXC" ]]; then
echo "error: buxc not found at $BUXC (run make build first)"
exit 1
fi
passed=0
failed=0
normalize() {
# Replace absolute path prefix with FILE, drop trailing blank lines
sed -E \
-e "s|$DIR/[^:]+:|FILE:|g" \
-e "s|$ROOT/[^:]+:|FILE:|g" \
-e "s|//+|/|g" \
| sed -e :a -e '/^\n*$/{$d;N;ba' -e '}'
}
for case_dir in "$DIR"/*/; do
name="$(basename "$case_dir")"
[[ -f "$case_dir/expected.err" ]] || continue
[[ -f "$case_dir/bux.toml" ]] || continue
out="$("$BUXC" build "$case_dir" --color off 2>&1 || true)"
got="$(printf '%s\n' "$out" | normalize)"
exp="$(cat "$case_dir/expected.err")"
# Compare ignoring full absolute path differences already normalized
if [[ "$got" == "$exp" ]]; then
echo " PASS $name"
passed=$((passed + 1))
else
echo " FAIL $name"
echo "---- expected ----"
printf '%s\n' "$exp"
echo "---- got ----"
printf '%s\n' "$got"
echo "--------------"
failed=$((failed + 1))
fi
done
echo "Error golden tests: $passed passed, $failed failed"
if [[ $failed -gt 0 ]]; then
exit 1
fi
@@ -0,0 +1,7 @@
[Package]
Name = "type_mismatch"
Version = "0.1.0"
Type = "bin"
[Build]
Output = "Bin"
@@ -0,0 +1,7 @@
error: type errors in project
error: cannot assign String to int
--> FILE:4:18
|
4 | let x: int = "hello";
| ^^^^^^^
= help: ensure the right-hand side type matches the left-hand side
@@ -0,0 +1,6 @@
import Std::Io::PrintLine;
func Main() -> int {
let x: int = "hello";
return 0;
}
+7
View File
@@ -0,0 +1,7 @@
[Package]
Name = "undeclared"
Version = "0.1.0"
Type = "bin"
[Build]
Output = "Bin"
@@ -0,0 +1,7 @@
error: type errors in project
error: undeclared identifier 'noSuchVar'
--> FILE:4:15
|
4 | PrintLine(noSuchVar);
| ^^^^^^^^^
= help: check the spelling, or import the symbol from the right module
@@ -0,0 +1,6 @@
import Std::Io::PrintLine;
func Main() -> int {
PrintLine(noSuchVar);
return 0;
}