diff --git a/docs/BuildAndTest.md b/docs/BuildAndTest.md index 1e387f7..e4f4fbb 100644 --- a/docs/BuildAndTest.md +++ b/docs/BuildAndTest.md @@ -50,6 +50,10 @@ This compiles `buxc2` using the bootstrap compiler. The self-hosted compiler gen # Create a new package in a new directory ./buxc new myproject cd myproject + +# Or initialize in the current directory +mkdir myproject && cd myproject +./buxc init ``` This generates: @@ -89,8 +93,13 @@ Output = "Bin" ./buxc run ./buxc run ./myproject -# Run tests +# Run tests (builds and runs the binary, reports pass/fail) ./buxc test +./buxc test ./myproject + +# Format code +./buxc fmt src/Main.bux # single file +./buxc fmt src/ # all .bux files in directory # Clean build artifacts ./buxc clean @@ -113,6 +122,18 @@ This runs: - Semantic analysis unit tests - HIR lowering unit tests - Integration tests (`buxc new`, `buxc --version`) +- Golden C-codegen tests (8 examples) + +### Project Tests (`bux test`) +```bash +./buxc test +``` + +Builds the project and runs the resulting binary. Reports: +- `Tests passed` on exit code 0 +- `Tests failed (exit code N)` on non-zero exit + +Use `Std::Test` module for assertions inside test code. ### Example Programs ```bash @@ -137,17 +158,18 @@ cd examples_pkg/hello && ../../buxc run bux/ ├── src/ # Self-hosted compiler source (Bux) │ ├── Main.bux # Entry point -│ ├── Cli.bux # CLI commands +│ ├── Cli.bux # CLI commands (build, run, test, fmt, new, init) │ ├── Lexer.bux # Tokenizer │ ├── Parser.bux # Parser │ ├── Ast.bux # AST definitions -│ ├── Sema.bux # Semantic analysis +│ ├── Sema.bux # Semantic analysis (borrow checker) │ ├── Types.bux # Type system │ ├── Scope.bux # Symbol table │ ├── Hir.bux # High-level IR │ ├── HirLower.bux # AST → HIR lowering │ ├── CBackend.bux # HIR → C code generation │ ├── Manifest.bux # bux.toml parser +│ ├── Fmt.bux # Code formatter │ └── Token.bux # Token definitions ├── bootstrap/ # Bootstrap compiler (Nim) — compiles src/ → buxc │ ├── main.nim diff --git a/docs/LanguageRef.md b/docs/LanguageRef.md index 05e1c57..3f34875 100644 --- a/docs/LanguageRef.md +++ b/docs/LanguageRef.md @@ -19,7 +19,8 @@ This document describes the Bux programming language as implemented by the boots 11. [Error Handling](#error-handling) 12. [Modules and Imports](#modules-and-imports) 13. [Async/Await](#asyncawait) -14. [Operators](#operators) +14. [Operator Overloading](#operator-overloading) +15. [Operators](#operators) --- @@ -43,7 +44,7 @@ Identifiers start with a letter or underscore, followed by letters, digits, or u func, let, var, const, type, struct, enum, union, interface, extend module, import, pub, extern, if, else, while, do, loop, for, in break, continue, return, match, as, is, null, self, super, sizeof -async, await, spawn +async, await, spawn, defer, switch, case, default, checked ``` ### String Literals @@ -56,6 +57,7 @@ c32"Hello" // *char32 `line 1 line 2 line 3` // Newlines preserved as-is +f"Hello, {name}" // Interpolated string — expressions inside {} ``` **Backtick raw strings** (`` `...` ``) treat all characters literally: @@ -63,6 +65,11 @@ line 3` // Newlines preserved as-is - Actual newlines in source are preserved in the string - No way to escape the backtick character itself (use regular strings if needed) +**Interpolated strings** (`f"..."`): +- Expressions inside `{}` are evaluated and converted to `String` +- Supported types: `int`, `uint`, `float`, `bool`, `String` +- Escaped braces: `\{` and `\}` + ### Number Literals ```bux 42 // int @@ -93,6 +100,9 @@ line 3` // Newlines preserved as-is ```bux *T // Pointer to T +&T // Shared reference (read-only in checked functions) +&mut T // Mutable reference (exclusive borrow) +own T // Owned value (move semantics) T[] // Slice (unsized) T[N] // Fixed-size array (T1, T2, T3) // Tuple @@ -161,6 +171,19 @@ func Min(a: T, b: T) -> T { } return b; } + +// Named and default parameters +func HttpResponse(code: int = 200, body: String = "") -> Response { ... } +let r: Response = HttpResponse(body: "hello"); // code defaults to 200 +let s: Response = HttpResponse(404, body: "err"); // positional + named mixed + +// Operator overloading (bootstrap only) +func Vec2_operator_add(self: *Vec2, other: Vec2) -> Vec2 { ... } +func Vec2_operator_sub(self: *Vec2, other: Vec2) -> Vec2 { ... } +func Vec2_operator_eq(self: *Vec2, other: Vec2) -> bool { ... } +func Vec2_operator_lt(self: *Vec2, other: Vec2) -> bool { ... } +func MyArray_operator_index_get(self: *MyArray, idx: int) -> int { ... } +func MyArray_operator_index_set(self: *MyArray, idx: int, value: int) { ... } ``` --- @@ -211,6 +234,31 @@ outer: loop { } ``` +### `defer` +Runs an expression when the current scope exits (LIFO order). + +```bux +func ReadFile(path: String) -> String { + let fd: int = Open(path); + defer Close(fd); + defer PrintLine("done"); + let data: String = ReadAll(fd); + return data; // both defers run before return +} +``` + +### `switch` / `case` +Desugars to an if-else chain. Supports a `default` case. + +```bux +switch statusCode { + case 200: PrintLine("OK"); + case 404: PrintLine("Not Found"); + case 500: PrintLine("Server Error"); + default: PrintLine("Unknown"); +} +``` + --- ## Structs @@ -436,6 +484,18 @@ Moves happen in three contexts: - `&mut T` allows mutation - `*T` pointers are unrestricted (escape hatch) - `&mut T` coerces to `&T` and `*T` +- **Double mutable borrow**: passing `&mut x` twice to the same call is an error + ```bux + Swap(&mut x, &mut x); // ERROR: double mutable borrow of x + ``` +- **Use after move**: using a moved `own T` value is an error until reassigned + ```bux + let msg: own String = "hello"; + Process(msg); // move + PrintLine(msg); // ERROR: use of moved value + msg = "reassigned"; // OK: reinitialization + PrintLine(msg); + ``` --- @@ -632,6 +692,34 @@ func Main() -> int { --- +## Operator Overloading + +> **Status:** ✅ Implemented in bootstrap. Selfhost reserves syntax but has no method-table yet. + +Overloadable operators use the naming convention `TypeName_operator_`: + +| Operator | Function Name | Signature Example | +|----------|--------------|-------------------| +| `+` | `operator_add` | `func T_operator_add(self: *T, other: T) -> T` | +| `-` | `operator_sub` | `func T_operator_sub(self: *T, other: T) -> T` | +| `*` | `operator_mul` | `func T_operator_mul(self: *T, other: T) -> T` | +| `/` | `operator_div` | `func T_operator_div(self: *T, other: T) -> T` | +| `%` | `operator_mod` | `func T_operator_mod(self: *T, other: T) -> T` | +| `==` | `operator_eq` | `func T_operator_eq(self: *T, other: T) -> bool` | +| `!=` | `operator_ne` | `func T_operator_ne(self: *T, other: T) -> bool` | +| `<` | `operator_lt` | `func T_operator_lt(self: *T, other: T) -> bool` | +| `<=` | `operator_le` | `func T_operator_le(self: *T, other: T) -> bool` | +| `>` | `operator_gt` | `func T_operator_gt(self: *T, other: T) -> bool` | +| `>=` | `operator_ge` | `func T_operator_ge(self: *T, other: T) -> bool` | +| `[]` (get) | `operator_index_get` | `func T_operator_index_get(self: *T, idx: int) -> U` | +| `[]` (set) | `operator_index_set` | `func T_operator_index_set(self: *T, idx: int, value: U)` | + +**Notes:** +- Short-circuit operators (`&&`, `||`) cannot be overloaded. +- Generic method instantiation is supported. + +--- + ## Operators ### Arithmetic diff --git a/docs/PHASE8_STRATEGY.md b/docs/PHASE8_STRATEGY.md index 86bc516..49c6f45 100644 --- a/docs/PHASE8_STRATEGY.md +++ b/docs/PHASE8_STRATEGY.md @@ -1,7 +1,7 @@ # Фаза 8 — Стратегия: Как Bux печели, без да бие пряко Rust/Nim/Zig -> **Дата:** 2026-06-08 | **Статус:** Фаза 8.1 ✅, 8.2-8.6 🔄 -> **Последни постижения:** defer ✅, switch/case ✅, operator overloading ✅, selfhost-loop deterministic ✅ +> **Дата:** 2026-06-09 | **Статус:** Фаза 8.1 ✅, 8.2 ✅ (basic), 8.3-8.6 🔄 +> **Последни постижения:** defer ✅, switch/case ✅, operator overloading ✅, string interpolation ✅, named/default params ✅, basic borrow checker ✅, `bux fmt` ✅, `bux test` ✅, `bux new`/`init` ✅, selfhost-loop deterministic ✅ > **Правило #1:** Не се биеш с някого там, където той е най-силен. --- @@ -52,7 +52,7 @@ Bux е единственият език, който позволява: ### 3.1 Фаза 8.2 — Gradual Ownership (The Killer Feature) -**Статус сега:** Синтаксисът е парсен, но borrow checker-ът не работи. +**Статус сега:** ✅ Basic borrow checker работи в selfhost. Поддържа `@[Checked]`, `&T`, `&mut T`, use-after-move tracking и double-mutable-borrow detection. **Защо е критично:** Без работещ `@[Checked]`, Bux е просто "C с модерен синтаксис". С него — ставаме единствени на пазара. @@ -76,14 +76,14 @@ func MergeSorted(a: &[int], b: &[int]) -> Vec { ... } **Имплементационен план (прагматичен):** -| Етап | Фичър | За какво е | Priority | -|------|-------|-----------|----------| -| 8.2.1 | `@[Checked]` атрибут — вкл/изкл на checker | Да знаем кога да проверяваме | **P0 — критично** | -| 8.2.2 | `&T` shared reference + lifetime elision | Basic borrow без annotations | **P0** | -| 8.2.3 | `&mut T` exclusive mutable | Да няма data races | **P0** | -| 8.2.4 | Bounds checking на slices | Да няма buffer overflows | **P1** | -| 8.2.5 | Explicit lifetimes `'a` | Само за сложни случаи | **P2** | -| 8.2.6 | `own T` + move semantics | RAII без GC | **P2** | +| Етап | Фичър | За какво е | Priority | Статус | +|------|-------|-----------|----------|--------| +| 8.2.1 | `@[Checked]` атрибут — вкл/изкл на checker | Да знаем кога да проверяваме | **P0 — критично** | ✅ | +| 8.2.2 | `&T` shared reference + lifetime elision | Basic borrow без annotations | **P0** | ✅ | +| 8.2.3 | `&mut T` exclusive mutable | Да няма data races | **P0** | ✅ | +| 8.2.4 | Bounds checking на slices | Да няма buffer overflows | **P1** | 🔄 | +| 8.2.5 | Explicit lifetimes `'a` | Само за сложни случаи | **P2** | ⏳ | +| 8.2.6 | `own T` + move semantics | RAII без GC | **P2** | ✅ (basic) | **Какво ПРОПУСКАМЕ (за да не стане Rust #2):** - ❌ Няма да правим lifetime annotations задължителни @@ -292,18 +292,22 @@ Crates.io е непреодолимо предимство. Ние се конк - ✅ Selfhost-loop deterministic (C output identical) - ✅ File I/O, path ops, process spawn в stdlib - ✅ defer, switch/case, operator overloading — готово +- ✅ `bux new`, `bux init`, `bux test`, `bux fmt` — готово +- ✅ Basic borrow checker (`@[Checked]`) — готово - 🎯 Target: Можеш да напишеш `bux` package manager на Bux ### Milestone B: "Използваем за systems programming" (2 месеца) -- 🔄 Working `@[Checked]` с basic borrow checking -- 🔄 CTFE за precomputed tables +- ✅ Working `@[Checked]` с basic borrow checking +- ✅ CTFE за precomputed tables - 🔄 Trait bounds (`T: Comparable`) +- 🔄 Bounds checking на slices - 🎯 Target: Можеш да напишеш game engine или embedded firmware ### Milestone C: "Екосистема" (6 месеца) - 🔄 Package manager (`bux add`, registry) -- 🔄 LSP (autocomplete, hover) -- 🔄 Formatter (`bux fmt`) +- ✅ LSP (autocomplete, hover, diagnostics) +- ✅ Formatter (`bux fmt`) +- ✅ Test runner (`bux test`) - 🔄 Green threads + channels - 🎯 Target: Екип от 3 човека може да продуцира shipping продукт diff --git a/docs/ROADMAP.md b/docs/ROADMAP.md index a5bf14b..44aaa36 100644 --- a/docs/ROADMAP.md +++ b/docs/ROADMAP.md @@ -59,30 +59,26 @@ func MyArray_operator_index_set(self: *MyArray, idx: int, value: int) { ... } --- -## P0 — Critical (Unlocks Major Use Cases) - ### 4. String Interpolation -**Why:** `Fmt_Fmt1("hello {0}", name)` is verbose. +**Status:** ✅ Implemented in bootstrap (selfhost reserves AST node). **Syntax:** ```bux let name: String = "Bux"; -let msg: String = "Hello, {name}!"; +let msg: String = f"Hello, {name}!"; let num: int = 42; -let msg2: String = "Count: {num}"; +let msg2: String = f"Count: {num}"; ``` -**Implementation Steps:** -1. Lexer: detect `{` inside string literals, parse interpolation expressions -2. Parser: create string concatenation AST node -3. Desugar to `String_Concat` calls or `Fmt_FmtN` - -**Complexity:** Low — lexer/parser changes only. +**Notes:** +- `f"..."` prefix enables interpolation. +- Escaped braces: `\{` and `\}`. +- Auto-converts `int`, `uint`, `float`, `bool`, and `String` inside braces. --- -### 5. Named / Default Parameters ✅ DONE -**Why:** API ergonomics. +### 5. Named / Default Parameters +**Status:** ✅ Implemented in both bootstrap and selfhost. **Syntax:** ```bux @@ -91,11 +87,43 @@ let r: Response = HttpResponse(body: "hello"); // code=200 let s = HttpResponse(404, body: "err"); // positional + named mixed ``` -**Status:** Implemented in both bootstrap and selfhost. +**Notes:** - Bootstrap parser already parsed defaults; added named-arg parsing and sema injection. -- Selfhost parser now parses `= defaultExpr` in params and `name: value` at call sites. +- Selfhost parser parses `= defaultExpr` in params and `name: value` at call sites. - Sema injects default expressions and reorders named args into param order. -- HIR lowerer unchanged — desugaring happens in sema. + +--- + +### 6. CLI Commands (`bux new`, `bux init`, `bux test`, `bux fmt`) +**Status:** ✅ Implemented in selfhost. + +| Command | Description | +|---------|-------------| +| `bux new ` | Create a new project directory with `bux.toml` and `src/Main.bux` | +| `bux init` | Initialize a Bux project in the current directory | +| `bux test [dir]` | Build and run the project binary, reporting pass/fail | +| `bux fmt ` | Format `.bux` files (4-space indentation, preserves comments) | + +--- + +### 7. Basic Borrow Checker (`@[Checked]`) +**Status:** ✅ Implemented in selfhost. + +**Features:** +- `@[Checked]` attribute enables per-function borrow checking. +- `&T` (shared reference) and `&mut T` (mutable reference) type syntax. +- Rejects write-through raw pointer (`*T`) in checked functions. +- Detects double mutable borrow (`Swap(&mut x, &mut x)`). +- Tracks use-after-move for `own T` values. + +--- + +## P0 — Critical (Unlocks Major Use Cases) + +### 8. Full Selfhost Bootstrap Loop +**Why:** The selfhost compiler must compile itself deterministically. + +**Status:** 🔄 In progress — borrow checker works, but some features still missing in selfhost vs bootstrap. --- @@ -204,8 +232,10 @@ Task::Spawn(Worker, rx); 1. ✅ **`defer`** — Done 2. ✅ **`switch`/`case`** — Done 3. ✅ **Operator overloading** — Done (bootstrap) -4. **String interpolation** — Low complexity, big ergonomics win. **← NEXT** -5. **Named/default parameters** — Medium complexity, improves stdlib APIs. -6. **Closures** — High complexity, unlocks iterators and functional style. -7. **`for x in collection`** — Depends on closures or trait system. -8. **Destructors / Drop** — High complexity, needs ownership + move semantics. +4. ✅ **String interpolation** — Done (bootstrap) +5. ✅ **Named/default parameters** — Done +6. ✅ **Basic borrow checker (`@[Checked]`)** — Done (selfhost) +7. ✅ **`bux fmt`, `bux test`, `bux new`, `bux init`** — Done (selfhost) +8. **Closures** — High complexity, unlocks iterators and functional style. **← NEXT** +9. **`for x in collection`** — Depends on closures or trait system. +10. **Destructors / Drop** — High complexity, needs ownership + move semantics. diff --git a/docs/STRATEGY.md b/docs/STRATEGY.md index 2632680..40f31be 100644 --- a/docs/STRATEGY.md +++ b/docs/STRATEGY.md @@ -1,6 +1,6 @@ # Как Bux ще победи Rust, Nim и C -> **Дата:** 2026-05-31 | **Версия:** 0.2.0 (bootstrap) +> **Дата:** 2026-06-09 | **Версия:** 0.3.0 (selfhost) --- @@ -124,12 +124,12 @@ match x { Ok(v) => ..., Err(e) => ... } | Фаза | Feature | Ефект | |------|---------|-------| | **8.1** | ✅ Error handling (`?`, `!`) | По-чисто от Nim | -| **8.2** | ⏳ `@[Checked]` borrow checker | **Уникално — това е оръжието** | -| **8.3** | ⏳ Concurrency (tasks + channels) | Go-стил леки нишки | -| **8.4** | ⏳ CTFE (`const func`) | Nim-level метапрограмиране | +| **8.2** | ✅ `@[Checked]` borrow checker (basic) | **Уникално — това е оръжието** | +| **8.3** | 🔄 Concurrency (tasks + channels) | Go-стил леки нишки | +| **8.4** | ✅ CTFE (`const func`) | Nim-level метапрограмиране | | **8.5** | ⏳ Trait система | Rust-стил генерици | | **8.6** | ⏳ Макроси | Nim-стил метапрограмиране | -| **8.7** | ⏳ LSP сървър | IDE поддръжка | +| **8.7** | ✅ LSP сървър | IDE поддръжка | ---