Files
bux-lang/docs/QUALITY_PLAN.md
T
dimgigov ec5984762b
ci / build (ubuntu) (push) Has been cancelled
ci / unit + fmt (push) Has been cancelled
ci / examples (push) Has been cancelled
ci / goldens + tools (push) Has been cancelled
ci / apps (push) Has been cancelled
ci / selfhost smoke (push) Has been cancelled
ci / macos smoke (push) Has been cancelled
ci / windows smoke (push) Has been cancelled
ci / CI gate (push) Has been cancelled
selfhost-loop / bootstrap determinism (push) Has been cancelled
feat: try/unwrap payload types, LSP format, macro paste, freestanding runtime
- Type `?`/`!` as Result/Option Ok payload (not always int); fix unwrap C types
- LSP 0.18 document formatting (bux fmt) + VS Code format-on-save
- Macro `:type` generics (Array_New<$t>) and operators-only tt paste
- Ship runtime_freestanding.c + BUX_RUNTIME=freestanding + smokes/examples
2026-07-28 16:56:35 +03:00

75 KiB
Raw Blame History

Bux — План към „добър“ език (v0.5 → v1.0.0 )

Дата: 2026-07-27
Текущо: v1.0.0 — language freeze (session 88 / release)
Цел: Език, с който се пишат реални проекти комфортно, безопасно (по избор) и с надежден toolchain.
Платформен фокус: Linux (primary) · cloud-native (servers, containers, HTTP) · embedded (cross, freestanding-ish, CTFE).
Не-цел: MS Windows като product platform (исторически CI/hello smoke остават; няма roadmap investment).
Release notes: docs/RELEASE_v1.0.0.md · Semver: docs/SEMVER.md (active).


Диагноза (къде сме)

Слой Състояние Оценка
Frontend (lex/parse) Пълен Pratt parser, recovery ★★★★☆
Sema / generics Monomorphization, trait bounds basic ★★★★☆
HIR → C Tuples + fat func ABI в bootstrap и selfhost ★★★★☆
Selfhost (src/) ~12k LOC, binary-identical loop, closures+tuples ★★★★★
Gradual ownership @[Checked], move, Drop, elision, field-move + remaining-field Drop ★★★★★
Concurrency M:N tasks + channels + async ★★★★☆
Stdlib Array/Map/Set/String/Iter HOF разширени ★★★★☆
Tooling LSP 0.5 hover/def/outline/refs/rename + fmt/test/doc ★★★★★
Ecosystem / registry path+git + file + HTTP index (bux search/add) ★★★★☆
Документация README + QUALITY_PLAN синхронизирани (2026-07-15) ★★★★☆

Силна ниша: gradual ownership (C-скорост на писане + opt-in Rust-safety).
Слабо място: ergonomics на stdlib + maturity на tooling + пълнота на borrow checker.


Какво значи „добър“ за Bux

  1. Ежедневен DX — колекции, string, assert, грешки, които разбираш за секунди.
  2. Предвидима безопасност@[Checked] да хваща 80% от UAF/double-borrow без lifetime hell.
  3. Selfhost като dogfood — компилаторът и apps (nexus, boko) са proof.
  4. Инструменти — fmt, test, LSP, package install без ръчна магия.
  5. Стабилна спецификация — LanguageRef = реалното поведение.
  6. Целеви среди — Linux servers/containers, cloud HTTP services, embedded/cross (ARM/RISC-V), не desktop Windows.

Не целим „по-добър Rust“. Целим единствения език с gradual safety + Go-стил concurrency без GC, удобен за cloud + systems на Linux.


Фази

A — Ergonomics & Stdlib (P0) (core done)

# Задача Защо Статус
A.1 Array: Pop, Clear, IsEmpty, First, Last, Cap, Reserve Без това колекциите са неудобни (тази сесия)
A.2 String: IsEmpty, ReplaceAll Чести операции; само first-replace досега (тази сесия)
A.3 Os_Exit + Test_AssertEqString / richer asserts Тестове и CLI без raw bux_exit (тази сесия)
A.4 Map_Remove / Set polish Completeness на колекциите (тази сесия)
A.5 Iter: map/filter/fold върху closures Higher-order без boilerplate generic Iter_Map/Filter/Fold + Int aliases
A.6 Result helpers: Expect, UnwrapErr, Or По-малко match boilerplate (тази сесия)

B — Compiler Correctness (P0)

# Задача Защо Статус
B.1 Proper tuple types в C backend (T,U)Tuple_T_U struct + .0/.1 bootstrap + selfhost
B.2 Function pointer types func(T)->U fat ABI bootstrap + selfhost
B.3 Match expression lowering (literals, ranges, enums) Expression-context match → if-else bootstrap + selfhost
B.3b Pattern bindings (Some(value) => value) Payload idents bound in arm body bootstrap + selfhost
B.3c Match arm guards (p if cond => …) Bindings visible in guard; sequential found-flag lower bootstrap + selfhost
B.4 Closures multi-instance Fat BuxFn + heap env bootstrap + selfhost
B.4b Closures: || empty params + loop/return body Lexer || vs empty closure; while/break/return bootstrap + selfhost
B.5 По-добри diagnostics (snippet + hint) DX #1 за нови потребители
B.6 Bootstrap ↔ selfhost feature parity empty ||, match-as-expr, string interp f"..." bootstrap+selfhost

C — Gradual Ownership 2.0 (P1)

# Задача Защо Статус
C.1 Lifetime elision за common cases Без 'a в 90% от API-тата bootstrap + selfhost
C.2 Exclusive &mut vs shared & data-flow По-малко false negatives let-bound + use-while + call conflict
C.3 Auto-drop edge cases (early return, branches) RAII да е надежден bootstrap + selfhost
C.4 @[Release] zero-cost path документация + golden tests Killer story: safe default, free hot path full (docs + Release wins + tests + example)

D — Tooling (P1)

# Задача Защо Статус
D.1 LSP: hover, go-to-def, diagnostics IDE = adoption v0.11.0: + interface dispatch hierarchy
D.2 bux fmt стабилен + CI check Единен style full-tree format + make fmt-check enforce
D.3 bux test с --filter, exit codes, summary table CI-friendly --filter / summary / exit 0|1
D.4 bux doc от /// comments Самодокументиращ се stdlib bootstrap+selfhost + make docs
D.5 Golden tests за stdlib modules Регресии без изненади tests/stdlib_golden/ + make test-stdlib

E — Ecosystem & v1.0 (P2)

# Задача Защо Статус
E.1 Package registry protocol (git/HTTP) bux add foo без path hacks local index + HTTP(S) URL cache + file/git + search
E.2 35 production-quality apps в apps/ Showcase 4 apps + make test-apps smoke (build + CLI)
E.3 Language freeze + semver policy Trust v1.0.0 + active docs/SEMVER.md
E.4 Debugger/DWARF basics Systems audience #line.bux + -g / --release; make test-dwarf
E.5 Benchmarks vs C/Zig/Nim (micro + nexus) Marketing + regression micro + C/Nim/Zig twins + make bench-nexus (wrk)

Препоръчан ред на работа

A (stdlib ergonomics)  →  B (compiler holes)  →  C (ownership depth)
        ↓                        ↓
   D (tooling)  ←──────────  dogfood apps
        ↓
   E (v1.0 ecosystem)

Правило: всяка сесия ship-ва нещо runnable (stdlib API, fix, example), не само docs.


Acceptance criteria за „добър v1.0“ — met; tagged v1.0.0

  • Всички examples + apps + selfhost smoke на CI (make test via .github/workflows/ci.yml); selfhost-loop optional
  • Array/Map/String/Test API покрива 90% от ежедневните нужди (+ Insert/Remove/Clone/case/GetOr)
  • @[Checked] хваща use-after-move + double &mut + dangling return / elision fail
  • bux test + bux fmt + bux check са default developer loop (--filter / --check shipped)
  • LanguageRef синхронизиран с компилатора (incl. C.1 elision)
  • Поне един външен/temp проект build-ва с registry dep (tools/smoke_registry.sh + HTTP)
  • Version strings + SEMVER active + docs/RELEASE_v1.0.0.md (session 88)

Сесия 1 (stdlib ergonomics)

  1. Array_Pop, Array_Clear, Array_IsEmpty, Array_First, Array_Last, Array_Cap, Array_Reserve
  2. String_IsEmpty, String_ReplaceAll
  3. Os_Exit
  4. Test_AssertEqString, Test_AssertNeqInt, Test_AssertEqBool
  5. Example + docs update

Сесия 2 (collections + tuples)

  1. Map_Remove / Map_Clear / Map_IsEmpty (+ StringMap)
  2. Set_Remove / Set_Clear / Set_IsEmpty
  3. Result_Expect / Result_UnwrapErr / Result_Or
  4. Option_Expect / Option_Or
  5. Tuples: (T, U)typedef struct { T _0; U _1; } Tuple_T_U + field access .0/.1
  6. Examples: tuples, func_ptr, map_remove

Сесия 3 (diagnostics + collections)

  1. Rust-style errors in bootstrap CLI: --> file:line:col, source snippet, ^ caret, = help: hints
  2. SourceLocation.file propagated from lexer
  3. Better caret for type-mismatch on let (points at initializer)
  4. Array_Contains / Array_IndexOf / Array_Extend
  5. Iter_AnyEq / Iter_AllEq / Iter_Collect
  6. Selfhost Diagnostic_Hint for common messages

Сесия 4 (diagnostics depth + LSP + strings)

  1. Multi-char underlines (^^^^^^^ under tokens/strings/idents)
  2. Quoted-name highlighting for undeclared identifier 'x'
  3. Golden error tests (tests/error_golden/, make test-errors)
  4. LSP runs buxc check and publishes real diagnostics
  5. String_IsBlank / String_Repeat

Сесия 5 (multi-instance closures)

  1. Fat function pointers for all func(...) types: BuxFn { code(env, args...), env }
  2. Capturing closures: heap-allocate env per creation site (independent instances)
  3. Capture-less closures + named funcs: adapters with env = NULL
  4. Calls through func values: f.code(f.env, args...)
  5. Example multi_closure.bux — MakeAdder(10)/MakeAdder(20) yield 11 and 21
  6. Selfhost parity: same fat ABI in src/hir_lower.bux + src/c_backend.bux (makers, adapters)

Сесия 6 (selfhost tuples)

  1. Parser: (T, U) types, (a, b) exprs, field access .0/.1
  2. Sema: tekTuple / ekTuple
  3. HIR lower → hStructInit of Tuple_int_int
  4. C backend: typedef struct Tuple_int_int { int _0; int _1; }
  5. Verified with buxc2 on examples/tuples.bux

Сесия 7 (Iter HOF)

  1. Iter_MapInt / FilterInt / FoldInt / ForEachInt / AnyInt / AllInt / SumInt
  2. Named funcs + capturing closures (fat ABI)
  3. Example iter_hof.bux (sum=15, product=120)
  4. Selfhost fix: pointer -> field access; no bogus bounds check on arr.data[len] (Push)

Сесия 8 (match expression + error goldens)

  1. Match expression lowering (B.3): pkLiteral, pkRange (a..b / a..=b), enum tags, wildcard
    • Bugfix: literal arms were always-true (else branch) → match 1 { 1=>10, 2=>20 } returned 10 for all
    • skMatch now also lowers via lowerMatch (void result)
  2. Expanded examples/pattern_matching.bux (enums + classify ranges + string arms)
  3. Error golden cases (tests/error_golden/):
    • parse_error — incomplete let x = ;
    • use_after_move@[Checked] + own String
    • double_mut_borrow — two &mut of same var
  4. run.sh normalize: absolute paths in "parse errors in …" lines

Сесия 9 (selfhost match — B.6 parity)

  1. AST: MatchArm linked list; Pattern.patChild1/2 for ranges; Expr.matchArms
  2. Parser: full parserParsePattern / parserParseMatchExpr (was skip-arms stub)
    • literals, _, ident, Enum::Variant / Enum::Variant(...), ranges
    • statement matchskExpr + ekMatch
  3. Sema: type-check subject + arms; propagate first-arm type to expr.refType
  4. HIR lower: Lcx_LowerMatch → alloca result + if-else stores (enum .tag / simple / literal / range)
  5. Last-expr return: Lcx_LowerBlock converts final skExpr into return (needed for func F() -> T { match ... })
  6. Verified: pattern_matching via buxc2; simple enum + ranges; selfhost-loop IDENTICAL ✓

Сесия 10 (pattern bindings — B.3b)

  1. Bootstrap sema: extractPatternBindings resolves enum payload field types from variant decl
  2. Bootstrap HIR: matchPatternBindingsalloca name; name = subject.data.Variant_i before arm body
  3. Match result type: fall back to currentFuncRetType when arm bodies only use bindings
  4. Multi-field enum layout: positional fields.len > 1 → nested struct in _Data union (no overlay)
  5. Selfhost: parse patArgs linked list; Sema_BindPattern; Lcx_PatternBindings in match arms
  6. Example: pattern_matching.bux uses Option::Some(value) => value (real binding, not opt.data.Some_0)
  7. Verified: bootstrap + buxc2 + all examples + error goldens + selfhost-loop IDENTICAL ✓

Сесия 11 (empty || closures + match-as-expr — B.4b)

  1. Bug: || -> int { ... } lexed as tkPipePipe (logical-or), not two tkPipe → empty-param closures failed to parse
  2. Fix bootstrap: primary of tkPipePipe: → zero-param ekClosure
  3. Fix selfhost: parserParseEmptyClosure for tkPipePipe
  4. Match-as-expr: expression-form match now skips newlines (same as statement form) → let x = match n { ... } works
  5. Verified control-flow in closure body: while/break, early return from loop, multi-return if-chain
  6. Pattern bind reuse: one alloca per binding name per function (patternBoundNames) so two matches can both use v
  7. Selfhost match-as-expr: let-init + binary operands expand yield blocks (Lcx_IsMatchYield / __binop_N)
  8. Examples: closure_control.bux, match_let.bux
  9. Verified: bootstrap + buxc2 + all examples + error goldens + selfhost-loop IDENTICAL ✓

Сесия 12 (string interpolation selfhost — B.6)

  1. Selfhost parser: parserParseStringInterp — interleaved lit/expr parts in callArgs, nested fragment parse via Lexer_Tokenize + sub-parser
  2. Selfhost sema/HIR: ekStringInterpString_Concat + String_FromInt/FromBool/FromFloat
  3. Bootstrap fix: f"plain" no longer keeps the f prefix in the literal; \{/\} preserved by lexer and unescaped by interp parser
  4. Lexer: \{ / \} allowed (bootstrap + selfhost) so LanguageRef escape rules work
  5. Compiler hygiene: original dense &&/|| in the large interp loop caused bootstrap OOM (~27GB) when compiling parser.bux — rewrite with simpler control flow
  6. Example: examples/string_interp.bux (name/int/bool/plain/escaped braces)
  7. Verified: bootstrap + buxc2 + all 41 examples + error goldens + selfhost-loop IDENTICAL ✓

Сесия 13 (LSP hover / go-to-def / outline — D.1)

  1. Richer symbol index: func signatures (params + -> Ret), let/var/const with types, struct/enum/union/interface/type/module
  2. Skip comments/strings during scan (no false func hits)
  3. Hover: markdown bux signature + kind; accurate word range
  4. Go-to-definition: current file + workspace index (scan .bux under rootUri)
  5. Document symbols (outline) via textDocument/documentSymbol
  6. didChange refreshes symbols immediately; didSave/didOpen still run buxc check diagnostics
  7. Fix: responses write to stdout (was writing to stdin stream → broken pipe)
  8. Version bux-lsp 0.2.0; smoke-tested via JSON-RPC

Сесия 14 (generic Iter map/filter/fold)

  1. Iter_Map<T,U> / Filter<T> / Fold<T,Acc> / Any / All / ForEach — fat func params + monomorphization
  2. Int aliases keep working: Iter_MapIntIter_Map<int,int>, …
  3. Bootstrap fixes:
    • call return type for local fat-func (f: func(T)->U) after mono (was always int → String map truncated pointers)
    • generic call Foo<T>(…) now type-checks args (closures get capture analysis)
  4. Selfhost fixes:
    • Lcx_SubstituteType recurses into tekFunc (was leaving BuxFn_U_T)
    • fat typedef emit covers cstr shapes + #ifndef guards
  5. Example: examples/iter_generic.bux (int↔String map, filter, fold, closures)
  6. Verified: bootstrap + buxc2 + selfhost-loop IDENTICAL ✓

Сесия 15 (struct/tuple patterns)

  1. Tuple patterns: match t { (a, b) => a + b } — bind subject._0 / ._1
  2. Struct patterns: Point { x: px, y: py } + shorthand Point { x, y }
  3. Bootstrap: matchPatternBindings for pkTuple/pkStruct; field types from struct decl; range registration of local tuple typedefs
  4. Selfhost: parse () / Name { … } patterns; Sema_BindPattern + Lcx_PatternBindings with Scope_Define
  5. Fix: operator-overload path treated String_Eq(null, "") as non-empty → crash on a + b after pattern bind
  6. Example: examples/struct_tuple_pat.bux
  7. Verified: bootstrap + buxc2 + selfhost-loop IDENTICAL ✓

Сесия 16 (match block arms + block expressions)

  1. Block-as-expression: let r = { let x = 1; x + 2 } — last skExpr is the value
  2. Multi-stmt match arms: 1 => { PrintLine("…"); let a = 10; a + 1 }
  3. Bootstrap: lowerBlock(..., asExpr) promotes last expression; nested enum/struct pattern bindings
  4. Selfhost: parse { … } as ekBlock; yield temps __blk_N; fix IsMatchYield null-strValue false positive; retTypeKind -2 for expr blocks
  5. Nested: Shape::Dot(Point { x, y }) works on bootstrap; selfhost covers struct/tuple/enum + block arms
  6. Example: examples/match_block.bux
  7. Verified: bootstrap + buxc2 + selfhost-loop IDENTICAL ✓

Сесия 17 (deeper nested patterns + multi-field enum layout)

  1. Multi-field payload type: nested struct Enum_Variant_Payload (suffix avoids clash with tag Enum_Variant)
  2. Bootstrap: full resolveTypeExpr for enum field types (tuples/pointers); sema synthetic field lookup on payload types; data.Two.Two_0 construction
  3. LIR C backend: emit tuple typedefs before enums that embed them; topo deps for *_Payload
  4. Selfhost: enum variants parse full types (parserParseType) — fixes Val((int,int)); store fieldTypeName*; structs before enums (e.g. Dot(Point))
  5. Patterns: Pair::Two(a, b), Box::Val((a, c)), Shape::Dot(Point { x, y }) + block arms
  6. Example: examples/nested_patterns.bux
  7. Verified: bootstrap + buxc2 + selfhost-loop IDENTICAL ✓

Сесия 18 (match arm guards — B.3c)

  1. Syntax: p if cond => body (also after ranges: 1..10 if x % 2 == 0)
  2. Parser fix (critical): isTypeArgListAhead treated x < 0 as generic when a later x > 0 existed in another arm → infinite parse. Stop lookahead on =>, keywords, literals, arithmetic, comparisons.
  3. Sema: bind inner pattern first; type-check guard as bool in arm scope
  4. HIR lower: sequential found flag (no shared if-else DAG):
    if (!found) { if (inner_cond) { binds; if (guard) { result = body; found = true; } } }
    
    Bindings are in scope for the guard expression.
  5. Selfhost: pkGuarded + patGuardExpr; same lower strategy; fix return match {…} to expand yield block before return
  6. Example: examples/match_guards.bux (ident/literal/range/enum payload guards)
  7. Verified: bootstrap + buxc2 + all examples + error goldens + selfhost-loop IDENTICAL ✓

Сесия 19 (generic HOF type inference)

  1. Bootstrap inferTypeArgs: structural unify of param TypeExpr vs arg Type
    • *Iter<T> / *Array<T> → extract T from pointee type args or mangled Array_int
    • func(T)->U → bind T/U from function-value type (not whole func as T)
    • bare Acc from init; multi-param Iter_Fold<T,Acc>
  2. Selfhost: improved Sema_InferGenericArgs + return-type subst after inference
    • Fix: ekCast must type-check operand (was skipping → no inference under as)
    • HIR fallback mono from first *Array/*Iter arg when count=0
  3. Works without explicit type args:
    • Array_Push(&nums, 1), Array_Get, Array_Len, Array_Iter
    • Iter_Map(&it, f), Iter_Filter, Iter_Fold, Iter_Any (int↔String)
  4. Example: examples/generic_infer_hof.bux
  5. Verified: bootstrap + buxc2 + all examples + selfhost-loop IDENTICAL ✓

Сесия 20 (LSP hover from real sema — D.1)

  1. bux-lsp 0.3.0 links bootstrap (--path:../bootstrap) and runs analyzeFull on open/save
  2. typeIndex: global scope (stdlib + file) → hover signatures with real types
  3. File-local priority: user decls override stdlib name collisions (Max<T> vs Math.Max)
  4. Locals: walk function bodies for let/var with explicit type annotations
  5. didChange: fast lightweight rescan; keeps previous typeIndex until save/hover refresh
  6. Hover shows bux signature + _kind_ · sema
  7. Smoke: Main() -> int, PrintLine(String) -> void, Max<T>(a: T, b: T) -> T

Сесия 21 (pattern binding shadowing)

  1. Problem: C/LIR function-scoped locals — nested Some(n) => match … Some(n) emitted store before int n, and let v + pattern v caused redeclaration.
  2. Bootstrap: every pattern binding → unique C name __pN_src via patternRenames map; body/guard idents rewritten; binds before body lower inside lowerMatch.
  3. Selfhost: same model — Lcx_BindPatIdent + patMapFrom/To rename table; arm-scoped push/pop of map.
  4. Semantics: nested pattern name shadows correctly; outer let v survives after match that binds v.
  5. Example: examples/pattern_shadow.bux
  6. Verified: bootstrap + buxc2 + all examples + selfhost-loop IDENTICAL ✓

Сесия 22 (Ownership 2.0 — C.2 + C.4 + *p= fix)

  1. C.2 Exclusive &mut data-flow (@[Checked]):
    • Track long-lived let-bound borrows (activeMutBorrows / activeSharedBorrows)
    • Reject: second &mut x, use/assign of x while mutably borrowed, &x while &mut live
    • Call-site temps conflict with existing let-bound borrows
  2. C.4 Golden tests:
    • tests/error_golden/exclusive_mut_let/
    • tests/error_golden/use_while_mut_borrow/
  3. Bugfix: *p = expr now stores through the pointer (was assigning to a temp) — ownership examples finally mutate correctly
  4. Example: examples/ownership_checked.bux (unchecked zero-cost + checked OK path)
  5. Verified: 7 error goldens + borrow_test + all examples + selfhost-loop

Сесия 23 (Ownership 2.0 — C.3 auto-drop early return / branches)

  1. Bootstrap auto-drop for @[Drop] + collections:
    • Parser: @[Drop] / @[Release] on structs and funcs (declAttrs)
    • autoDropFuncName + monomorphize Array_Drop/Free (etc.) so stdlib links
    • Inject Type_Drop(&x) on let via deferStmts
  2. Early return / multi-path:
    • Every return snapshots the full live defer stack (no clear-after-first-return)
    • Materialize return value before Drop (return a.id is not use-after-drop)
    • Move-on-return: skip Drop for a local returned by value (return out)
  3. Branch / loop scopes:
    • Bootstrap: lowerBlock scopes deferStmts — branch-local drops at block exit; siblings do not see each other
    • Selfhost C backend: CBE_EmitDefers keeps stack for multi-return; CBE_EmitAndPopDefersFrom pops branch/loop locals after if/while/loop
  4. Selfhost fixes: null-safe ret type; temp name counter; use function retTypeName for __retdrop_N
  5. Example: examples/drop_early_return.bux (Early + Branched + Scoped → 5 drops)
  6. Verified: bootstrap + buxc2 drop tests, 7 error goldens, key examples, selfhost-loop IDENTICAL ✓

Сесия 24 (tooling — D.2 fmt --check + D.3 test --filter)

  1. Bootstrap bux fmt (bootstrap/fmt.nim):
    • Indent-by-brace-depth formatter (parity with src/fmt.bux)
    • bux fmt [path...] writes; bux fmt --check exits 1 if any file would change
    • Collects single file or recursive .bux under directories
  2. Bootstrap bux test --filter:
    • --filter <s> / --filter=<s> — only run tests/*.bux whose name contains s
    • Summary table (PASS / FAIL[:code]) + Results: N passed, M failed, T total
    • Exit 0 all pass, 1 failures or no match
  3. Selfhost parity (src/cli.bux, src/fmt.bux):
    • Fmt_WouldChange / Fmt_CheckFile; Cli_Fmt(dir, checkOnly)
    • Cli_Test(dir, filter) with summary + skip count; filter skips Main package run
  4. CI hooks: make fmt-check smoke (clean→0, dirty→1); full-tree enforce deferred until a one-shot format pass on lib//examples/
  5. Idempotence fix: drop trailing split-empty so re-format is a no-op
  6. Verified: unit suite + ./buxc test --filter first _test_runner + selfhost buxc2 fmt/test parity

Сесия 25 (Ownership 2.0 — C.1 lifetime elision)

  1. Elision rules in @[Checked] (bootstrap/sema.nim):
    • Each elided input &/&mut → distinct #elidedN
    • One input lifetime → assigned to elided return
    • First param self/Self preferred when multiple inputs
    • Multiple inputs + elided return → lifetime elision failed (need 'a)
  2. Return checks:
    • cannot return reference to local variable (return &local / let-bound local ref)
    • no input reference to borrow from (return ref with zero input refs)
    • Explicit 'a mismatch between return and value
  3. Body check for lifetime-only generics (func F<'a>(...)) — no longer skipped
  4. Diagnostics hints for elision / dangling / mismatch
  5. Tests: 8 new borrow_test cases; goldens return_local_ref, elision_multi_input
  6. Example: examples/lifetime_elision.bux (Identity / explicit / ViaLet / self)
  7. LanguageRef + QUALITY_PLAN updated
  8. Verified: borrow_test 24/24, 9 error goldens, example runs

Сесия 26 (C.1 selfhost parity)

  1. Lexer (src/lexer.bux + tkLifetime=111): 'a vs char 'x' (same heuristic as bootstrap)
  2. Parser:
    • &'a T / &'a mut TTypeExpr.refLifetime
    • func F<'a, T>(…) — lifetime params accepted and skipped for mono slots
  3. Sema lifetime elision (fixed 8-slot maps, same rules as bootstrap):
    • single-input elision, self preference, multi-input fail
    • return-local / no-input-ref / explicit mismatch
    • let-bound ref lifetime propagation
  4. Fixed checkFunc else-branch that wiped checkedFunc when retType was void
  5. Verified: buxc2 run lifetime_elision PASS; goldens on buxc2 show same errors; bootstrap still green; selfhost-loop expected IDENTICAL

Сесия 27 (tooling — D.4 bux doc + D.5 stdlib goldens)

  1. D.5 Stdlib goldens (tests/stdlib_golden/):
    • Packages: array, string, collections (Map/Set/Result/Option)
    • run.sh builds via buxc run and matches expected PASS lines
    • make test-stdlib wired into make test
  2. D.4 bux doc:
    • Bootstrap: bootstrap/docgen.nim/// + adjacent /* */
    • Selfhost: Cli_Doc line scanner for ///
    • bux doc [--out file] [path] (default path lib/)
    • make docsdocs/api/stdlib.md
  3. Stdlib docs: /// on Array / String / Test public helpers
  4. Verified: make test-stdlib, ./buxc doc lib/Array.bux | head, selfhost build

Сесия 28 (LSP v0.4.0 — position-sensitive locals + inferred lets)

  1. LocalBinding with scope range (scopeStartLinescopeEndLine) per let/param
  2. Sema-backed inference (checkExprForLsp / resolveType):
    • let x = 42 → hover let x: int · inferred
    • let s: String = "…" → annotated, not inferred
    • params: param a: int visible for whole function
  3. Position-sensitive hover / go-to-def / completion (innermost scope wins on shadowing)
  4. Nested scopes: if/while/for/match/block arms
  5. Version bux-lsp 0.4.0; tests: tools/test_lsp_locals.nim, tools/smoke_lsp_hover.sh
  6. Verified: hover shows let sum: int · inferred, param a: int, let n: int · inferred

Сесия 29 (full-tree bux fmt + CI enforce)

  1. One-shot format of lib/ (33), examples/ (23), src/ (15), tests/ (8), apps/ (12)
  2. Idempotent: second --check → 0 would reformat on all trees
  3. CI: make fmt-check enforces full tree + dirty-path smoke (exit 1)
  4. make fmt helper to reformat the same roots
  5. Verified: test-stdlib, key examples, selfhost + selfhost-loop IDENTICAL ✓

Сесия 30 (E.1 package registry + E.3 semver draft)

  1. Registry index (config/registry.toml, $BUX_REGISTRY, ~/.bux/registry.toml)
    • [[package]] with name / version / source / description
    • file: / path: (relative to index) or git URL
  2. CLI: bux search [q], bux add <name> resolves registry, bux install locks path/git
  3. Demo package: registry/packages/greet (Greet_Hello, Greet_Version)
  4. Smoke: tools/smoke_registry.sh / make test-registry — temp app outside tree
  5. Semver policy: docs/SEMVER.md (0.x vs 1.0, registry version match)
  6. Packages.md updated

Сесия 31 (E.1b HTTP registry + E.2 apps smoke + E.5 micro-bench)

  1. HTTP registry index (bootstrap/registry.nim):
    • $BUX_REGISTRY accepts http:// / https:// URLs
    • Fetch via curl (fallback wget) → ~/.bux/cache/registry_http.toml
    • BUX_REGISTRY_REFRESH=1 forces re-download; cache keyed by URL meta file
    • bux search shows URL + cached path; clear errors on fetch failure
  2. Smoke: tools/smoke_registry.sh — local path flow + python http.server HTTP search
  3. E.2 apps smoke (tools/smoke_apps.sh / make test-apps):
    • Build simpledb, jwt-pitbul, nexus, boko-framework
    • simpledb set/get/has/count/del; jwt-pitbul sign/verify/decode
    • Removed obsolete JWT-disable workaround from simpledb README
  4. E.5 micro-benchmarks (benches/micro, benches/c, make bench):
    • Bux: int_loop, fib30, string_concat, array_push
    • C refs (gcc -O2): fib30, int_loop for relative comparison
  5. Docs: Packages.md, config/registry.toml, benches/README.md
  6. Verified: make test-registry, tools/smoke_apps.sh, tools/bench.sh

Сесия 32 (E.5 nexus throughput + language twins)

  1. Nexus env config (apps/nexus/src/Main.bux):
    • NEXUS_PORT, NEXUS_WORKERS, NEXUS_BIND, NEXUS_PUBLIC
  2. Throughput harness (tools/bench_nexus.sh / make bench-nexus):
    • Start nexus on :18080, wrk -t4 -c64 -d5s/api/health
    • Sample (this machine): ~44.5k req/s, p50 ~0.94ms (Connection: close)
  3. Language twins for micro kernels:
    • benches/nim/ fib + int_loop (nim c -d:release)
    • benches/zig/ sources (built when zig is on PATH)
    • make bench runs Bux + C + Nim (+ Zig if present)
  4. Docs: benches/README.md, nexus README, BuildAndTest
  5. Verified: tools/bench.sh, tools/bench_nexus.sh

Сесия 33 (E.4 Debugger / DWARF basics)

  1. Source map: HIR loc → LIR locLine/locFile on every stmt/expr (setSourceLoc)
  2. C backend: emit #line N "path.bux" when location changes; force map at each func entry
  3. Build modes:
    • default: cc -O0 -g + #line maps
    • --release / build --release: -O2 -DNDEBUG, no #line, no -g
    • BUX_CFLAGS appended for custom flags
  4. Smoke: tools/smoke_dwarf.sh / make test-dwarf
    • #line for stdlib + user Main.bux
    • .debug_info present in debug binary
    • gdb list Main shows real Bux source
  5. Verified: smoke PASS; gdb list Main → hello.bux body

Сесия 34 (LSP refs/rename + CI wiring)

  1. bux-lsp 0.5.0 (tools/lsp_server.nim):
    • textDocument/references — scoped locals (same binding via lookupLocalAt) + workspace globals
    • textDocument/prepareRename + renameWorkspaceEdit.changes
    • Ident scan skips strings/comments; keyword rename rejected
  2. Smoke: tools/smoke_lsp_rename.sh (sum→total ≥2 edits); wired into make test-lsp
  3. CI: make test now runs test-registry + test-dwarf + test-apps after stdlib goldens
  4. Verified: rename/hover smokes PASS

Сесия 35 (Nexus HTTP/1.1 keep-alive)

  1. Server loop (apps/nexus/src/Server.bux):
    • HandleConnection serves up to 1000 requests per TCP fd
    • BuildResponse(..., keepAlive)Connection: keep-alive + Keep-Alive: or close
  2. Policy (RawRequest_WantsKeepAlive on raw bytes):
    • HTTP/1.1 default keep-alive; Connection: close forces close
    • HTTP/1.0 needs explicit keep-alive
    • (Avoided fragile Array<HeaderEntry> walk — keys corrupted under for-in/Get)
  3. Bench: ~81k req/s vs ~45k with close-only (wrk -t4 -c64 -d5s /api/health)
  4. Version banner 0.3.0; README / benches notes updated
  5. Verified: curl headers + make bench-nexus

Сесия 36 (header ownership + selfhost flags + LSP workspace/symbol)

  1. Root cause (Nexus headers UAF): auto-drop of local headers after shallow-copy into HttpRequest / ParseResult freed the buffer while still referenced. Not Array ABI — move-out-of-field not tracked.
  2. Fix (apps/nexus/src/Parser.bux): after embedding, zero headers.data/len/cap so auto-drop is a no-op; Request_WantsKeepAlive again uses RequestHeader_Get safely. Bench still ~7680k RPS.
  3. Selfhost compile flags (src/cli.bux):
    • default -O0 -g (was always -O2)
    • --release-O2 -DNDEBUG (was -O3 -flto)
    • BUX_CFLAGS appended via bux_getenv
    • #line maps remain bootstrap-only (selfhost C backend has no LIR #line yet)
  4. LSP 0.6.0: workspace/symbol over open docs + workspace index (cap 200); tools/smoke_lsp_workspace.sh + make test-lsp
  5. Verified: nexus keep-alive + header Get; make lsp + workspace smoke

Сесия 37 (compiler: field-move skip auto-Drop)

  1. Root cause (formal): auto-Drop of locals that were moved by value into a struct field / let / return still ran → UAF (Nexus headers in HttpRequest).
  2. bootstrap/hir_lower.nim:
    • movedOutLocals: HashSet[string]
    • markMovedOutFromAst on ekStructInit fields, let init, return value
    • shouldSkipDrop at return / block exit / function tail
  3. Nexus: removed zeroing workaround; error path still Drops; success path transfers ownership; HandleConnection Drops req.headers after response
  4. Example: examples/move_field.bux (Array into Box { items })
  5. Verified: move_field PASS; ParseRequest C has Drop only on error path; bench-nexus ~88k RPS; drop_early_return still 5 drops

Сесия 38 (selfhost field-move + #line)

  1. Field-move Drop (src/c_backend.bux):
    • CBE_MarkMovedFromNode on hStructInit / return values (nested fields)
    • Already skipped Drop via CBE_IsMoved in defer emit
  2. Struct emit fix (src/hir_lower.bux):
    • Field types Array<int>Array_int (etc.) so parent structs are not skipped as “generic” (was incomplete typedef struct Box Box only)
  3. #line maps (selfhost C backend):
    • Emit #line N "file" on statements when node.line > 0
    • BUX_DEBUG_FILE sets the path; BUX_NO_LINE=1 disables
  4. Verified: selfhost move_field PASS; Make() has no Array_Drop(&items) after field move; #line points at .bux sources

Сесия 39 (LSP 0.7 deeper rename)

  1. Member index in analyzeFile:
    • struct/union/interface fields (name: Type)
    • enum variants (Name / Name(...))
  2. Access classification for each hit:
    • bare / .member / ::Variant / name: field-init
  3. Rename targets:
    • local — same binding only (shadowing-safe)
    • member — decl + .x + ::Red + { x: }not bare locals named x
    • global — bare + :: paths; skips .member false positives
  4. Smoke: tools/smoke_lsp_rename_deep.sh (x→px ≥3, Red→Crimson ≥2, local x→xx =2)
  5. Version bux-lsp 0.7.0; wired into make test-lsp

Сесия 40 (LSP 0.8 call hierarchy)

  1. Providers:
    • textDocument/prepareCallHierarchy
    • callHierarchy/incomingCalls — who calls F
    • callHierarchy/outgoingCalls — what F calls
  2. Graph: textual scan of known func symbols + Name( call sites; enclosing function via nearest prior func decl line
  3. Skips the declaration itself; workspace disk scan for other .bux files
  4. Smoke: tools/smoke_lsp_call_hierarchy.sh (Add ← Compute; Compute → Add/Mul)
  5. Version bux-lsp 0.8.0; make test-lsp

Сесия 41 (selfhost multi-file #line paths)

  1. Decl.sourceFile stamped when parsing/merging each .bux file (Cli_StampSourceFile / Cli_MergeFileInto / project src/ loop)
  2. HirFunc.sourceFile copied in Lcx_LowerFunc
  3. C backend: before each function, set currentFile from sourceFile and emit #line 1 "path" + per-stmt #line N "path"
  4. No env required — stdlib + user multi-file paths appear automatically (lib/Fs.bux, ./src/Util.bux, ./src/Main.bux, …)
  5. Overrides: BUX_DEBUG_FILE (force one path), BUX_NO_LINE=1 (disable)
  6. Verified: multi-file project runs; #line paths distinct per source

Сесия 42 (selfhost CI smoke)

  1. tools/smoke_selfhost.sh:
    • build/use buxc2 (make selfhost)
    • move_field: run PASS + no Array_Drop(&items) after field move
    • multi-file #line: Util.bux + Main.bux + lib/*.bux paths in main.c
  2. make test-selfhost-smoke depends on selfhost
  3. Wired into default make test
  4. Verified: smoke script PASS

Сесия 43 (LSP 0.9 method call hierarchy)

  1. Index methods in analyzeFile:
    • Track extend Type / impl Type brace body
    • func inside → kind method, container Type, detail Type.func …
  2. Call graph includes methods as callables
    • .Method( sites (iaDot) + free Func( calls
    • CallHierarchyItem: SymbolKind.Method (6), display Type.Method
    • data field keeps bare name for graph match
  3. Smoke: tools/smoke_lsp_method_hierarchy.sh
    • ScaleLen; MainScale; prepare on method
  4. Version bux-lsp 0.9.0; make test-lsp

Сесия 44 (LSP 0.10 method + type + receiver rename)

  1. rtkMethod: rename method decl + .Method( + bare Method(
    • (previous global path skipped iaDot → broke method rename)
  2. Type rename (isType): struct/extend Type/self: Type/ctors; skip .field
  3. self receiver: synthetic local when sema omits method params; clip to enclosing func body via textual bounds (sibling methods safe)
  4. Smoke: tools/smoke_lsp_rename_method.sh
    • Len→Length ≥2, Point→Vec2 ≥4, self→this =3 (one method only)
  5. Version bux-lsp 0.10.0; make test-lsp

Сесия 45 (LSP 0.11 interface dispatch hierarchy)

  1. Index:
    • interface I { func M… } → iface methods + symbol
    • extend Type for Iimpls relation + implementor methods
  2. Call hierarchy:
    • prepare on interface method → item with data: "I#M", kind Interface
    • outgoing on iface method → implementor methods (dispatch targets)
    • incoming on iface method → callers of .M(
  3. Smoke: tools/smoke_lsp_iface_hierarchy.sh
    • Drawable.Draw → Circle implementor; Render → Draw
  4. Version bux-lsp 0.11.0

Сесия 46 (LSP 0.12 module-path segment rename)

  1. Index import A::B::C / import A::B::{…} path segments (PathSegInfo)
  2. rtkPathSeg rename with left-prefix match:
    • Std::Io → only segments under prefix Std (not Foo::Io, not bare Io)
    • path head Std only when followed by :: (not bare locals)
    • does not clobber enum Color::Red (member path still wins on variants)
  3. Last import segment that is also a known symbol falls through to global rename
  4. Workspace scan for unopened .bux files
  5. Smoke: tools/smoke_lsp_rename_path.sh
    • Io→Net ≥2 (Main+Util), not Foo::Io; Std→Core ≥2; Red→Crimson ≥2
  6. Version bux-lsp 0.12.0; make test-lsp

Сесия 47 (HirNode-level sourceFile / mid-function #line)

  1. HirNode.sourceFile — per-statement path for #line (rare multi-file spans)
  2. Lcx_StampSourceFile: after lowering a func/closure body, fill empty node paths from Decl.sourceFile / HirFunc.sourceFile (keeps pre-set paths)
  3. LowerCtx.currentSourceFile + closures inherit enclosing file
  4. C backend: lastDebugFile + prefer node.sourceFile over func currentFile; re-emit #line when line or file changes mid-function
  5. BUX_DEBUG_FILE truly forces one path (no longer overwritten by per-func)
  6. Smoke: tools/smoke_selfhost.sh — Util_Double body #line → Util.bux only
  7. make test-selfhost-smoke / rebuild selfhost

Сесия 48 (optional CI: selfhost-loop)

  1. tools/selfhost_loop.sh: bootstrap determinism (buxc × 2)
    • path-normalized #line C compare (abs path / build-dir noise stripped)
    • stripped ELF compare; fails on real C or ELF mismatch
  2. Lexer: maxTokens 32k → 131k (hir_lower was at the ceiling for buxc2 parse)
  3. Optional fixed-point BUX_SELFHOST_FIXED_POINT=1: buxc2 → buxc3
    • experimental; selfhost still diverges on full compiler C emit
  4. GitHub Actions .github/workflows/selfhost-loop.yml
    • workflow_dispatch (+ optional fixed_point input)
    • weekly cron (Sunday 06:00 UTC)
    • push to main when src/ / lib/ / loop script change
    • not on every PR / not in default make test
  5. Verified: make selfhost-loop PASS (determinism)

Сесия 49 (LSP 0.13 textDocument/implementation)

  1. implementationProvider + textDocument/implementation
  2. Interface type under cursor → locations of implementing types (extend Type for Iface / type decl)
  3. Interface method under cursor → implementor method decls (reuses collectImplementorFuncs + workspaceImpls)
  4. Also: call-site / shared method name matching known iface methods; implementor method → sibling implementors of same iface method
  5. Smoke: tools/smoke_lsp_implementation.sh
    • Drawable → ≥2 types; Draw → ≥2 methods (Circle + Square)
  6. Version bux-lsp 0.13.0; make test-lsp

Сесия 50 (LSP 0.14 workspace import path index)

  1. workspaceImportPaths: URI → full import paths (["Std","Io"])
  2. registerWorkspaceImports at end of analyzeFile (scan + open/edit)
  3. isKnownImportPathPrefix uses workspace index first — no open doc required
  4. Path segment snapshot fix (no shared seq mutation across segments)
  5. Smoke: tools/smoke_lsp_workspace_imports.sh
    • only Main opened; Util closed on disk via rootUri scan
    • Io→Net ≥2 edits including Util.bux in WorkspaceEdit
  6. Version bux-lsp 0.14.0; make test-lsp

Сесия 51 (Expr/Stmt sourceFile for multi-file / macros)

  1. Expr.sourceFile / Stmt.sourceFile / Block.sourceFile
  2. Ast_StampExprFile / Ast_StampStmtFile / Ast_StampBlockFile / Ast_StampPatternFile — fill empty slots only (grafted nodes keep path)
  3. Cli_StampSourceFile stamps decl body + const init + default params
  4. Lower: Lcx_SetNodeLoc / Lcx_SourceFileFor prefer AST file, else currentSourceFile; Lcx_StampSourceFile still fills empties at func end
  5. Smoke: Main body #line → Main.bux only (no Util leak); Util isolation kept
  6. Rebuild selfhost; make test-selfhost-smoke

Сесия 52 (selfhost fixed-point buxc2→buxc3→buxc4 green)

  1. Sema global scope: allocate via Scope_New (8192), not 1024 — heap overflow on ~1200 decls crashed buxc2 in Scope_Lookup
  2. HIR buffers: funcs 512→4096, structs 64→512, enums/consts/gen* raised
  3. CBE_FuncParam: avoid nested .paramN.name on *HirParam (wrong . vs ->)
  4. Adapters: __fat_env not env (no clash with CtfeEnv* env)
  5. Unary !: parenthesize operand so !(a && b)!a && b
  6. Fat typedef skip-void: rewritten without nested ! for older gens
  7. Fixed-point loop: compare gen2 vs gen3 (same CBE), not bootstrap vs selfhost
  8. Verified: BUX_SELFHOST_FIXED_POINT=1 make selfhost-loop — C+ELF IDENTICAL

Сесия 53 (main CI workflow — make test)

  1. .github/workflows/ci.yml
    • triggers: pull_request, push to main, workflow_dispatch
    • job: install Nim 2.0.x + gcc/make/ssl → make test
    • timeout 90m; concurrency cancel-in-progress
    • failure artifact: selfhost main.c (best-effort)
  2. selfhost-loop.yml remains optional (not on every PR)
  3. Docs: README / BuildAndTest / QUALITY_PLAN point to ci vs selfhost-loop

Сесия 54 (LSP 0.15 type hierarchy)

  1. typeHierarchyProvider + prepare / supertypes / subtypes
  2. prepare on struct / enum / interface / type → TypeHierarchyItem
  3. subtypes of interface → types with extend T for I (Circle, Square)
  4. supertypes of type → interfaces it implements
  5. Uses open-doc impls + workspaceImpls + symbol resolve
  6. Smoke: tools/smoke_lsp_type_hierarchy.sh
  7. Version bux-lsp 0.15.0; make test-lsp

Сесия 55 (macro / quote hygiene foundation)

  1. AST graft API (force overwrite): Ast_GraftExpr/Stmt/Block/PatternFile
  2. Clone: Ast_CloneExpr/Stmt/Block/Pattern (+ list / match arms)
  3. Quote policies:
    • Ast_QuoteDefSite — clone, keep sourceFile (macro body / template)
    • Ast_QuoteCallSite / Ast_QuoteStmtCallSite — clone + graft call-site path
  4. Helpers: Ast_SetExprLoc / Ast_ExprSourceFile
  5. HIR: Lcx_GraftSourceFile; mono instances force-graft genDecl.sourceFile
  6. Smoke: tools/smoke_graft_hygiene.sh (Array mono → lib; Main no leak)
  7. Wired into make test-selfhost-smoke

Сесия 56 (CBE binary parentheses — C precedence safety)

  1. Bug (selfhost): tree HIR→C emitted nested binaries without parens.
    • return (a + b) * c → C return a + b * c;7 instead of 9
    • return (a - b) / ca - b / c8 instead of 3
  2. Fix selfhost (src/c_backend.bux):
    • hBinary always emits (left op right) (same policy as bootstrap HIR CBE)
    • Unary operand parens (session 52) kept: !(a && b)
  3. Bootstrap LIR (bootstrap/lir_c_backend.nim): defensive parens on arith/bitwise and unary !/-/~ (operands are temps today; future-proof)
  4. Example: examples/c_precedence.bux — MulSum/SubDiv/ShiftSum/Mix
  5. Smoke: tools/smoke_selfhost.sh checks run values and generated C contains (a + b) * c / (a - b) / c
  6. Wired into EXAMPLES + make test-selfhost-smoke
  7. Verified: bootstrap + buxc29/3/6/7 + PASS c_precedence; smoke PASS

Сесия 57 (CI split jobs + macOS smoke)

  1. .github/workflows/ci.yml — no longer one 90m monolithic make test:
    • build (ubuntu): make build → artifact buxc-linux
    • Parallel (reuse artifact, BUX_SKIP_BUILD=1):
      • unitfmt-check + test-unit
      • examplestest-examples
      • goldens — errors + stdlib + registry + dwarf
      • appstest-apps
      • selfhosttest-selfhost-smoke
    • macos: Homebrew OpenSSL + rebuild + fmt/unit/examples
    • ci-gate: single required status (all of the above must succeed)
  2. Makefile:
    • test-unit extracted from test
    • ensure-buxc + BUX_SKIP_BUILD=1 for CI artifact reuse
    • $(OUT) rebuild only when bootstrap/*.nim changes
    • portable examples runner (optional timeout; macOS without coreutils OK)
  3. macOS / non-GNU ld:
    • bootstrap: -Wl,--build-id=none only when defined(linux)
    • selfhost: bux_cc_ld_stable() in rt/runtime.c (Linux-only build-id)
    • CI sets BUX_CFLAGS=-I… -L… for Homebrew libcrypto
  4. Docs: BuildAndTest + README CI table; local make test still full sequential
  5. Verified locally: BUX_SKIP_BUILD=1 make fmt-check test-unit test-errors

Сесия 58 (LSP 0.16 workspace type hierarchy index)

  1. Gap: type hierarchy subtypes/supertypes only saw open-doc impls or method-keyed workspaceImpls. Closed files with empty extend T for I {} (no methods) returned [].
  2. workspaceTypeRels (tools/lsp_server.nim):
    • URI → seq[(typeName, iface, line)] from every analyzeFile
    • registerWorkspaceTypeRels replaces per-URI (re-open / re-scan safe)
    • filled on scanWorkspace + open/edit — no open doc required
  3. Consumers:
    • collectSubtypeItems / collectSupertypeItems prefer type-rel index
    • collectTypeImplementorLocs (textDocument/implementation) same
  4. Smoke: tools/smoke_lsp_type_hierarchy_ws.sh
    • open only Main; Drawable.bux + Shapes.bux closed
    • empty extends → Drawable subtypes Circle+Square; Circle supers Drawable+Named
  5. Version bux-lsp 0.16.0; wired into make test-lsp
  6. Verified: single-file hierarchy + workspace smoke PASS

Сесия 59 (user-facing macro! / quote! — declarative MVP)

  1. Syntax (bootstrap):
    • macro! name { ($x:expr, …) => { template } }
    • Invoke: name!(args…) — distinct from unwrap expr! via following (
    • Built-in quote!(e) — identity expand + call-site graft
  2. Lexer: keyword macro; $ident fragment tokens ($x)
  3. AST: dkMacro + MacroRule/MacroFragment; ekMacroCall
  4. Expansion (bootstrap/macroexpand.nim) before sema:
    • Collect macro decls; match rule by arity
    • Deep clone + substitute $frags + graft call-site SourceLocation
    • Nested expand (depth ≤ 32)
  5. CLI: build / check / run call expandMacros after merge
  6. Example: examples/macro_twice.bux → 42 / 42 / 43 + PASS
  7. LanguageRef: Macros section (limits documented)
  8. Verified: ./buxc run macro_twice; hello + lexer/parser tests green
  9. Not yet: selfhost expand parity; $(…)* repetition; more frag kinds

Сесия 60 (selfhost macro! / quote! expand parity)

  1. Lexer/token: tkMacro, keyword macro, $ident fragments
  2. AST: dkMacro (rules in childDecl1 chain), ekMacroCall
  3. Parser: macro! name { ($x:expr) => {…} }, invoke name!(…)
  4. src/macroexpand.bux:
    • collect macros → match rule by arity → clone+subst $frags
    • call-site graft (line/col/sourceFile)
    • built-in quote!(e)
  5. CLI: expand before sema (project / check / compile paths)
  6. Sema fixes (needed for block templates):
    • ekBlock value = last skExpr type (was always tyVoid)
    • let x: T = … sets sym.typeKind from annotation (not only init)
  7. Smoke: tools/smoke_selfhost.sh runs examples/macro_twice.bux via buxc2
  8. Verified: buxc2 + bootstrap → 42/42/43 + PASS macro_twice

Сесия 61 (macro $(…)* + ident/tt fragments)

  1. Fragment kinds: expr | ident | tt (tt ≡ expr for now)
  2. Pattern rep (trailing): $( $x:expr ),* / $( $x:expr )*
  3. Template rep: $( stmts… )*skMacroRep, expanded per list item
  4. Lexer: bare tkDollar for $(…) (vs $ident)
  5. Bootstrap macroexpand.nim: list bindings, match rules, gensym locals
  6. Selfhost parity: useNames encodes kinds/rep:, Subst_Block_Flat, gensym
  7. Sema: block-as-expr checks last value inside child scope (no UAF of locals)
  8. Example: examples/macro_repeat.bux — sum_n / empty / call0 / id_tt
  9. Verified: bootstrap + buxc26/0/42/7 + PASS macro_repeat

Сесия 62 (C.4 @[Release] polish + Checked docs)

  1. Three-tier model documented in LanguageRef:
    • default (no checks) → @[Checked]@[Release] (force off)
  2. Bootstrap: releaseFunc; checkedFunc = Checked ∧ ¬Release
  3. Selfhost: same rule; stacked attrs loop (@[Checked] + @[Release])
  4. Parser: multi-line stacked @[…] (skip newlines between attrs)
  5. Tests (borrow_test): Release alone; Checked+Release wins; Checked still errors
  6. Example: examples/ownership_release.bux — Unchecked / Safe / Hot / HotDangle
  7. Verified: 27/27 borrow tests; example PASS

Сесия 63 (nested $(…)* / multi-rep / compound zip)

  1. Bootstrap (macroexpand.nim + parser):
    • Compound rep: $( $a:expr, $b:expr ),* → parallel lists, zip in template
    • Multi-rep: $(…)* ; $(…)* with call-site ; groups (exprMacroGroupLens)
    • Nested template: outer binds list → inner $(…)* expands once (no list names left)
    • MacroFragment.names / .kinds for multi-name frags
  2. Selfhost parity (src/macroexpand.bux, parser.bux):
    • Two named rep lists + zip in Subst_Block_Flat
    • Kinds encoding rep:expr+expr,@2 / multi-seg rep:…;rep:…
    • Macro call ; groups → genericCallee group-length string
  3. Example: examples/macro_nested.bux
    • add_pairs → 33, sum_groups → 63, double_each_sum → 14, named_sum → 18
  4. LanguageRef: multi-rep / compound / nested docs; limits updated
  5. Verified: bootstrap + buxc2 → PASS macro_nested / macro_repeat / macro_twice

Сесия 64 (CI Nim cache + faster macOS)

  1. Nim pin + toolchain cache:
    • NIM_VERSION: 2.0.8 (stable cache keys; was 2.0.x)
    • Cache .nim_runtime on build / unit / macos / selfhost-loop
    • Skip setup-nim-action on cache hit; restore PATH only
  2. nimcache project-local:
    • Makefile NIMFLAGS ?= --nimcache:nimcache for bootstrap + unit tests
    • actions/cache keyed on bootstrap/**/*.nim (+ tests for unit)
  3. Leaner macOS job:
    • Runner macos-14; timeout 35m
    • make test-unit + make test-examples-smoke (not full EXAMPLES / not fmt)
    • EXAMPLES_SMOKE: hello, ownership*, strings, map, c_precedence, macro_*
    • OpenSSL: install only if missing (brew list)
  4. Docs: BuildAndTest CI table; .gitignore .nim_runtime/
  5. Verified locally: make build uses nimcache/; test-examples-smoke PASS

Сесия 65 (Drop / RAII docs — field-move story)

  1. LanguageRef — Drop and RAII (under Gradual Ownership):
    • @[Drop] vs extend T for Drop (static Type_Drop, no vtable)
    • When auto-drop runs (block end, early return, branches) — not gated on Checked
    • Field-move skip Drop with MakeBox + simplified C (no Array_Drop(&items))
    • Move-on-return, assignment, call-arg transfers; error-path still Drops
    • Limits: whole-local moves, static dispatch, manual free pitfalls
  2. TOC links Ownership + Drop; Stdlib Array_Drop + Std::Drop section
  3. README Drop line mentions field-move
  4. Cross-refs: examples/move_field.bux, examples/drop_early_return.bux, selfhost smoke
  5. Verified: move_field C has no Array_Drop on moved items; example PASS

Сесия 66 (macro hygiene + frag kinds literal / block)

  1. Fragment kinds (bootstrap + selfhost):
    • literal / lit — only ekLiteral (rejects 1 + 2)
    • block — only ekBlock { … }
    • Shared fragMatches / Macro_FragMatches at match time
  2. Hygiene gensym:
    • Bootstrap: also rename for binders; walk for bodies in collect
    • Selfhost: gensym skFor + recurse if/while/for/MacroRep bodies
    • CBE: two with_acc!__m1_n / __m2_n (no collision)
  3. Example: examples/macro_hygiene.bux → 11/21/7/3/42 + PASS
  4. LanguageRef: kind table + hygiene layers (graft + gensym)
  5. Makefile: macro_hygiene in EXAMPLES + EXAMPLES_SMOKE
  6. Verified: bootstrap + buxc2; negative only_lit!(1+2) → no matching rule

Сесия 67 (CI Windows smoke)

  1. .github/workflows/ci.ymlwindows job (windows-latest, bash shell):
    • Cache Nim 2.0.8 (prebuilt zip — fast) + nimcache
    • nim c -o:buxc.exe bootstrap
    • Pure Nim unit tests: lexer / parser / sema / hir / borrow
    • CLI smoke: buxc.exe new + --version
  2. Scope (honest): no bux run examples on Windows yet — rt/runtime.c is POSIX (ucontext, pthread, sockets, OpenSSL link). Job still gates bootstrap regressions on Win.
  3. ci-gate: windows is a required job
  4. Docs: BuildAndTest CI table + Windows note
  5. Locally: YAML validated; full Win run is on GHA only

Сесия 68 (partial field moves + Drop goldens)

  1. Bug: return bag.items still ran Bag_Drop(&bag) → double-free / corrupt Array (ASSERT fail). Also dead double-Drop after terminal return.
  2. Bootstrap (hir_lower.nim):
    • markMovedOutFromAst handles ekField when field type is droppable (autoDropFuncName) — not for return a.id (int)
    • Scope exit: skip re-emitting drops when last stmt always-returns; pop defers
  3. Selfhost (c_backend.bux):
    • CBE_MarkMovedFromNodeHint + droppable type check; return uses currentRetType
    • Store/let rhs walks field access for partial moves
  4. Example + golden smoke:
    • examples/move_field_partial.bux
    • tools/smoke_drop_move.sh + make test-drop-move (CI goldens job)
  5. Verified: partial PASS; TakeItems has no Bag_Drop; drop_early_return 5; move_field PASS

Сесия 69 (macro unhygienic binders)

  1. Problem: gensym renamed all template let/var binders, so var $name: int = … with $name:ident could not introduce a call-site name.
  2. Bootstrap (macroexpand.nim):
    • binderIdentFromFrag + expandUnhygienic set
    • substStmt: rewrite skLet/skFor binder when name is $frag → ekIdent
    • collectLetNames skips unhygienic names
  3. Selfhost (macroexpand.bux):
    • Env_AddUnhy / Env_IsUnhy / Env_BinderFromFrag
    • Subst_Stmt rewrites binders; Macro_GensymBlock(ex, body, env) skips them
  4. Example: examples/macro_unhygienic.bux → 11/21/6/10/1 + PASS
    • C: counter / other / n kept; acc / scratch__mN_*
  5. LanguageRef: unhygienic binder table; EXAMPLES + EXAMPLES_SMOKE
  6. Verified: bootstrap + buxc2; macro_hygiene still PASS

Сесия 70 (per-field Drop + mono defer restore)

  1. Bug (critical): lowerFunc restored deferStmts / movedOutLocals only when the inner mono function still had pending defers. Nested generateMethodInstancelowerFunc (e.g. Array_Len inside PeekTagAndTake) wiped the caller's Drop stack → leaked moved Arrays.
  2. Fix bootstrap: always restore deferStmts / movedOutLocals / partialMovedFields after lowering a function body.
  3. Per-field Drop after partial move:
    • Track partialMovedFields: local → {field names}
    • Skip parent Type_Drop; emit Drop for remaining droppable fields
    • emitDropOrPartial at return / block exit / function tail
  4. Selfhost CBE (c_backend.bux):
    • partial (var, field) slots + local type registry on hAlloca
    • CBE_EmitRemainingFieldDrops when skipping moved parent Drop
  5. Example + smoke:
    • examples/move_field_remaining.bux (PairBag left move → Tracked_Drop right)
    • tools/smoke_drop_move.sh checks PeekTag Array_Drop + remaining Tracked_Drop
  6. LanguageRef: remaining-field rule; limits updated
  7. Verified: bootstrap + buxc2 remaining/partial/move_field; smoke; EXAMPLES

Сесия 71 (Windows MinGW + hello smoke)

  1. rt/runtime_win.c — minimal runtime without pthread / ucontext / sockets / OpenSSL. Real alloc, strings, files, time, env; stubs for tasks/crypto/net.
  2. Bootstrap CLI (bootstrap/cli.nim):
    • Windows (or BUX_RUNTIME=win) copies runtime_win.c instead of runtime.c
    • Link: -ffunction-sections -Wl,--gc-sections -lm (no -pthread / -lcrypto)
    • Host gcc on Windows; .exe suffix on build/run
    • Fixed: -l libs after .c inputs (GNU ld order)
  3. CI (.github/workflows/ci.yml windows job):
    • MinGW via msys2/setup-msys2 (mingw-w64-x86_64-gcc)
    • tools/smoke_windows_hello.sh after unit/CLI smoke
  4. Docs: BuildAndTest CI table + rt/ tree
  5. Verified locally: normal hello + BUX_RUNTIME=win smoke PASS

Сесия 72 (macro stmt / pat fragments)

  1. Kinds: mfkStmt / mfkPat (+ aliases pattern, lit already)
  2. AST wrappers: ekMacroStmt / ekMacroPat (expand-only)
  3. Call-site parse:
    • stmt keywords → parseStmt → MacroStmt
    • _parsePattern → MacroPat
    • else expr; pat coerces via exprToPattern (ident/lit/path/call/tuple/struct/range)
  4. Expand:
    • coerceArg at match; store normalized MacroStmt/MacroPat
    • $s as skExpr splices MacroStmt into the statement list
    • $p as pkIdent pattern substitutes bound MacroPat
  5. Selfhost: same kinds, coerce, splice, pattern subst
  6. Example: examples/macro_stmt_pat.bux — setup/do_twice/matches/if_let_like
  7. LanguageRef kind table + docs
  8. Verified: bootstrap + buxc2 macro_stmt_pat PASS

Сесия 73 (nested a.b.c field-move Drop)

  1. Bootstrap (hir_lower.nim):
    • fieldPathFromAst → base local + path @["inner","items"]
    • partialMovedFields stores dotted paths ("inner.items")
    • remainingDropsAt recursive: exact path = skip; prefix = recurse; other droppable fields → Type_Drop(&(base.a.b))
    • Typed intermediate hFieldAccess so LIR/C keep Inner not int
  2. Selfhost CBE: full dotted path on mark; recursive CBE_EmitRemainingAt
  3. Example: examples/move_field_nested.buxouter.inner.items → 2 Tracked drops
  4. Smoke + EXAMPLES; LanguageRef nested path section
  5. Selfhost: recursive remaining drops + skip Drop when HasPartialMoved (struct emit multi-pass topo for Outer{Inner})
  6. Verified: bootstrap + buxc2 nested_drops=4 PASS; full test-drop-move

Сесия 74 (field moves through pointers)

  1. Pointer aliases: let p = &bag / p = &bagptrAliases[p] = bag
  2. fieldPathFromAst: peel (*p) (ekUnary tkStar); resolve alias to owner
  3. p.field (auto-deref) and (*p).field mark owner + path
  4. Nested via ptr: p.inner.items → owner + "inner.items"
  5. Selfhost CBE: alias slots + resolve in CBE_BaseVarName; record on store/assign
  6. Example: examples/move_field_ptr.buxptr_drops=5
  7. Smoke + LanguageRef; limits: local aliases only (not cross-function params)
  8. Selfhost: unary C parens fix (*p).field; alias slots + BaseVar resolve
  9. Verified: bootstrap + buxc2 ptr_drops=5 PASS; full test-drop-move

Платформен фокус (v0.5 → v1.0 )

Ниша Какво значи за Bux Статус / посока
Linux Host + CI + full rt/runtime.c (pthread, ucontext, sockets, OpenSSL) primary; macOS secondary smoke only
Cloud-native HTTP/HTTPS, registry (lock+HTTPS), containers, musl docs sessions 7579
Embedded Cross (--target), CTFE tables, thin runtime, no-GC story minimal + aarch64 + riscv64 smoke (85) + freestanding notes; bare-metal still spike
Windows Не е product target no further investment (existing MinGW hello = historical)

Правило: нов runtime / stdlib / CI effort отива към Linux + cloud + embedded. Windows-only work не влиза в следващи сесии.


Сесия 75 (Linux / cloud / embedded foundation)

  1. rt/runtime_minimal.c — thin runtime (no pthread / ucontext / sockets / OpenSSL); same feature surface as historical runtime_win.c, documented for Linux static/embed.
  2. Bootstrap CLI (bootstrap/cli.nim):
    • BUX_RUNTIME=full|minimal|thin|embed|win
    • --static / BUX_STATIC=1 → fully-static link; defaults to minimal runtime
    • --target <triple> → prefers <triple>-gcc, else clang -target; defaults minimal
    • BUX_CC override; thin link uses -ffunction-sections -Wl,--gc-sections -lm
  3. CTFE bitwise + hex (bootstrap/sema.nim):
    • ^ & | << >> in const eval
    • 0x / 0b / 0o integer literals in CTFE
  4. Example examples/ctfe_crc.bux — recursive CRC-8 table cells + Pow2(8) size
  5. Smoke tools/smoke_linux_targets.sh / make test-linux-targets:
    • minimal hello run
    • --static --release + file statically linked
    • --target aarch64-linux-gnu when cross-gcc present
    • ctfe_crc under minimal
  6. Container examples/docker/Dockerfile.static + tools/build_static_hello.sh
  7. CI goldens job installs gcc-aarch64-linux-gnu and runs test-linux-targets
  8. Docs: BuildAndTest + QUALITY_PLAN platform section

Verified: smoke 4/4 PASS; CRC_1=#define 7; aarch64 static ELF.


Сесия 76 (P0: ownership + macros + selfhost parity)

  1. Cross-function pointer ownership (bootstrap/hir_lower.nim):
    • TakeItems(&bag) where callee does return p.items / let x = p.items
    • Call site marks owner bag + partial path items; remaining fields still Drop
    • Example examples/move_cross_fn.bux + smoke in test-drop-move
  2. Macro $x:tt — broader than expr: any single call-site AST fragment (bootstrap + selfhost); example examples/macro_tt.bux
  3. Selfhost link parity (src/cli.bux):
    • --static, --target, BUX_RUNTIME, BUX_CC, BUX_STATIC
    • Cli_LinkProgram shared by single-file + project builds
    • Thin runtime → no pthread/OpenSSL; full → POSIX as before
  4. Docs: LanguageRef tt + QUALITY_PLAN

Verified: move_cross_fn PASS; macro_tt PASS; smoke_drop_move; buxc2 --static project → static ELF + Hello, Bux!.


Сесия 77 (selfhost cross-fn + Nexus production polish)

  1. Selfhost cross-fn ownership (src/c_backend.bux):
    • CBE_MarkCrossFuncFromCall scans callee HIR for p.field moves
    • Call site TakeItems(&bag) → partial move on bag (no double-free)
    • Verified: buxc2 run move_cross_fncross_fn_drops=2 PASS
  2. Runtime stop handlers (rt/runtime.c):
    • bux_install_stop_handlers / bux_should_stop / bux_set_stop_listen_fd
    • SIGINT/SIGTERM set flag + close listen fd (unblock accept)
    • Thin/win runtimes: no-op stubs
  3. Stdlib Os_InstallStopHandlers / Os_ShouldStop / Os_SetStopListenFd
  4. Nexus 0.4.0:
    • Graceful stop: main=acceptor; poison workers (fd=-1); exit on SIGTERM
    • Access log: METHOD path status ms (NEXUS_ACCESS_LOG)
    • Max body: NEXUS_MAX_BODY (default 1 MiB) → 413
    • Config fields + /api/health version 0.4.0
  5. TLS deferred (needs SSL context in runtime — not this session)

Verified: SIGTERM exits nexus; health JSON 0.4.0; access log lines; selfhost cross_fn.


Сесия 78 (Nexus TLS + container story)

  1. Runtime TLS (rt/runtime.c + OpenSSL libssl):
    • bux_tls_server_ctx / accept / send / recv / close / error
    • Thin/win: stubs; full POSIX links -lssl -lcrypto
  2. Stdlib Std::NetTls_ServerCtx, Tls_Accept, Tls_Send, Tls_Recv, …
  3. Nexus 0.5.0:
    • NEXUS_TLS=1 + NEXUS_TLS_CERT / NEXUS_TLS_KEY (PEM)
    • ConnectionTask.tls handle; ConnRecv/ConnSend dual plain/TLS
    • Banner https:// when TLS; SIGTERM still graceful
  4. Smoke tools/smoke_nexus_tls.sh / make test-nexus-tls (openssl self-signed + curl -k)
  5. Containers:
    • examples/docker/Dockerfile.nexus (debian-slim + libssl3)
    • examples/http_health.bux + Dockerfile.health + tools/build_health_bin.sh
  6. CLI link flags bootstrap + selfhost: -lssl -lcrypto

Verified: curl -k https://…/api/health → 0.5.0; SIGTERM exit; health binary HTTP.


Сесия 79 (registry lock/HTTPS + musl path)

  1. bux install lock checksums — sha1 of sorted *.bux sources per package
  2. bux install --locked — CI mode: verify paths + checksums; no re-resolve
  3. BUX_REGISTRY_INSECURE=1 — self-signed HTTPS registry fetch (curl -k)
  4. Smoke tools/smoke_registry.sh:
    • lock deterministic (diff two installs)
    • --locked ok / missing fail / checksum mismatch fail
    • HTTP + HTTPS self-signed index
  5. musl path tools/smoke_musl_static.sh / make test-musl-static
    • BUX_CC=musl-gcc or zig musl wrapper + BUX_RUNTIME=minimal --static
    • SKIP when toolchain absent (documented)
  6. Docs: Packages.md lock section; BuildAndTest musl; Dockerfile.alpine-health

Verified: registry smoke full PASS; musl SKIP (no toolchain on host).


Сесия 80 (selfhost install --locked + Nexus mTLS)

  1. Selfhost install / install --locked (src/cli.bux):
    • Write bux.lock with sha1 checksums (shell sha1sum of sorted *.bux)
    • --locked verifies paths + checksums (CI parity with bootstrap session 79)
    • Manifest: parse [Dependencies] + { Path = "..." } inline tables
  2. mTLS (rt/runtime.c bux_tls_server_ctx_ex):
    • Optional client CA → SSL_VERIFY_PEER | FAIL_IF_NO_PEER_CERT
    • Tls_ServerCtxMtls in Std::Net
    • Nexus NEXUS_TLS_CLIENT_CA → require client certs (v0.6.0)
  3. Smokes: tools/smoke_selfhost_install.sh, tools/smoke_nexus_mtls.sh
    • make test-selfhost-install / make test-nexus-mtls

Verified: selfhost lock/locked/mismatch; mTLS reject without cert + accept with cert.


Сесия 81 (selfhost full registry)

  1. src/registry.bux — load index from $BUX_REGISTRY / ~/.bux / config/registry.toml
    • HTTP(S) fetch via curl/wget → ~/.bux/cache/registry_http.toml
    • BUX_REGISTRY_REFRESH, BUX_REGISTRY_INSECURE (parity with bootstrap)
  2. CLI search / add <name> / add <name> <version|url>
  3. Build path deps — merge depUrl absolute/relative package src/ (not only deps/)
  4. Runtime discoveryBUX_STDLIB/../rt when building outside the monorepo tree
  5. Smoke tools/smoke_selfhost_registry.sh / make test-selfhost-registry

Verified: search greet; add+install+run Hello, Bux!; HTTP registry search.


Сесия 82 (CI cloud/selfhost smokes + polish)

  1. CI apps jobtest-nexus-tls + test-nexus-mtls (openssl + curl)
  2. CI selfhost jobtest-selfhost-install + test-selfhost-registry
  3. Registry pathsexpandFilename for file:/path: sources (no .. in lock)
  4. Docs already cover sessions 7581 platform stack

Verified: local smokes previously green; CI wiring ready for GHA.


Сесия 83 (stdlib daily API — collections_extra)

  1. Array (lib/Array.bux):
    • Array_RemoveAt — shift-left remove, returns value
    • Array_Insert — insert at 0..=len (append at end)
    • Array_SwapRemove — O(1) unordered remove
    • Array_Clone — shallow value clone into new buffer
  2. String (lib/String.bux):
    • String_Cmpstrcmp wrapper
    • String_IndexOf — byte index or -1
    • String_ToUpper / String_ToLower — ASCII only via StringBuilder
  3. Map (lib/Map.bux):
    • Map_GetOr / StringMap_GetOr — default when key missing
  4. Example examples/collections_extra.bux + Makefile EXAMPLES
  5. Goldens tests/stdlib_golden/{array,string} extended
  6. Docs docs/Stdlib.md tables updated

Verified: collections_extra PASS; make test-stdlib 3/3 PASS.


Сесия 84 (macro raw tt groups + expression-level $(…),*)

  1. Delimiter-balanced :tt groups (bootstrap + selfhost):
    • $args:tt that is a multi-element tuple (a, b) is wrapped as ekMacroTt with group flag
    • Splice $f($args) flattens to f(a, b) (not f((a, b)))
    • Value-position splice unwraps to the inner tuple / fragment
    • Contrast :expr keeps the tuple as one argument
  2. Expression-level rep in templates:
    • Parse $( expr ),* / $( expr )* inside call argument lists when macroTemplateMode
    • ekMacroRep expands to N call args (zip list fragments)
    • Example: apply_rep!(Add3, 1, 2, 3)Add3(1, 2, 3)
  3. Example examples/macro_tt_raw.bux + Makefile EXAMPLES / EXAMPLES_SMOKE
  4. Docs LanguageRef tt + expression-level rep + limits
  5. Hardening: CBE_NormalizeTypeName / String_StartsWith null-safe (fixed selfhost segfault on if_let_like + enum field-move path)

Verified: bootstrap + buxc2 macro_tt_raw PASS; macro_stmt_pat PASS; macro regressions OK.


Сесия 85 (riscv64 cross smoke + freestanding notes + slice :tt)

  1. riscv64 cross smoke (tools/smoke_linux_targets.sh):
    • Shared try_cross helper for aarch64 + riscv64
    • PASS when ${triple}-gcc present; SKIP otherwise (no false fail)
    • Documented: clang -target alone needs a sysroot
  2. Freestanding / bare-metal research (docs/BuildAndTest.md):
    • Table: thin/static/cross vs true freestanding / Cortex-M 🔬
    • Clarifies runtime_minimal still uses libc (not no-libc)
  3. Delimiter-balanced :tt + slice lit (session 84 extension):
    • [a, b] slice groups flatten like tuples in $f($args)
    • Selfhost parser: primary [a, b, …]ekSlice (parity with bootstrap)
    • examples/macro_tt_raw.bux case apply_tt!(Add, [8, 9]) → 17
  4. Docs: LanguageRef, BuildAndTest, Makefile target blurb

Verified: make test-linux-targets — minimal/static/aarch64/ctfe PASS; riscv64 SKIP; bootstrap + buxc2 macro_tt_raw (incl. slice) PASS.


Сесия 86 (free-form juxta :tt paste)

  1. Pattern juxtaposition: $f:ident $args:tt without comma between fragments (bootstrap + selfhost parser continue on next $…)
  2. Expand-time call split: when rule is exactly two fixed frags ident + tt and the call site has one arg that is ekCall with ident callee:
    • bind $f → callee
    • bind $args → MacroTt group of the calls arguments
    • $f($args) flattens as before → f(a, b)
  3. Example apply_juxta!(Add(2, 5)) / apply_juxta!(Add3(1, 2, 4)) in examples/macro_tt_raw.bux
  4. LanguageRef juxta section; comma form still works

Verified: bootstrap + buxc2 macro_tt_raw (h=7, i=7) PASS; macro regressions OK.


Сесия 87 (:type fragments + Array_Reverse / Test_AssertNeqString)

  1. Macro $t:type (bootstrap + selfhost):
    • Fragment kind type (type is a keyword — special-cased in parsers)
    • Call-site coerce: int → named; *int → pointer
    • Subst into sizeof($t), as $t, let x: $t
  2. Example examples/macro_type.bux — size_of / cast_zero + reverse/neq
  3. Stdlib: Array_Reverse, Test_AssertNeqString
  4. Docs: LanguageRef type table; Stdlib Array_Reverse

Verified: bootstrap + buxc2 macro_type PASS (sizeof int=4, *int=8).


Сесия 88 (v1.0.0 language freeze)

  1. Version banners: bootstrap + selfhost CLI → 1.0.0; root bux.toml → 1.0.0
  2. docs/SEMVER.mdActive (post-1.0 MAJOR = breaking)
  3. docs/RELEASE_v1.0.0.md — freeze notes + verify commands
  4. README / QUALITY_PLAN / ROADMAP status → v1.0.0
  5. Tag v1.0.0 after make test gate

Post-1.0 backlog (MINOR, not freeze blockers):

  • Generics in :type (Array<int>); operators-only tt paste session 5
  • runtime_freestanding.c session 5 (Cortex-M / board BSP still research)
  • LSP / IDE versioning independent of language MAJOR

Follow-up (2026-07-28)

  1. ? / ! payload types — bootstrap no longer hardcodes int; Ok/Some type from Result<T,E> / enum fields (bootstrap/sema.nim, hir_lower.nim).
  2. Example try_generic — String Result propagation.
  3. LSP 0.18textDocument/formatting (+ range) via formatSource / bux fmt; VS Code format-on-save default; tools/smoke_lsp_formatting.sh.
  4. Macros: generic :type + Array_New<$t>; operators-only $op($a,$b) / juxta binary split (examples/macro_type_generic, macro_op_paste).
  5. Freestanding: rt/runtime_freestanding.c, BUX_RUNTIME=freestanding, make test-freestanding.

Изрично не правим

  • Повече Windows examples / Win OpenSSL / Win sockets
  • Windows като required CI gate за product features (остава optional historical smoke ако CI вече го има)
  • Desktop GUI / Win32 APIs