Sessions 56–69: declarative macro! with rep/zip/literal/block and
unhygienic var $name binders; partial field-move skip Drop; @[Release]
polish; LSP type hierarchy; CI Nim cache + lean macOS + Windows smoke.
Add Ast_Graft/Clone/Quote helpers, HIR Lcx_GraftSourceFile, and force
definition-site paths on monomorphized bodies. Smoke checks Array mono
#line stays in lib while Main stays isolated.
Add tools/selfhost_loop.sh with path-normalized C and stripped ELF
checks (bootstrap ×2). Wire GitHub Actions (manual/weekly/main paths)
outside default make test. Raise selfhost lexer maxTokens for large files.
Index interface methods and extend Type for Trait relations so call
hierarchy can show implementors as outgoing targets and .Method call
sites as incoming.
- interface I { func M } + extend T for I tracking
- prepare/outgoing/incoming with data Iface#Method
- smoke_lsp_iface_hierarchy (Drawable.Draw ↔ Circle / Render)
Add rtkMethod so .Method( call sites rename with the method decl, improve
type renames across extend/annotations, and clip self to the enclosing
method body.
- Len→Length includes self.Len(); Point→Vec2 hits extend + types
- self→this stays within one method (textual func bounds)
- smoke_lsp_rename_method + test-lsp wiring
Add tools/smoke_selfhost.sh and make test-selfhost-smoke (via make selfhost)
to the default make test suite, covering field-move ownership and per-file
#line paths under buxc2.
Expose LSP call hierarchy over a lightweight textual call graph of
known functions and Name( call sites across the workspace.
- prepareCallHierarchy on func decl or call site
- incomingCalls / outgoingCalls with fromRanges
- smoke_lsp_call_hierarchy + test-lsp wiring
bux-lsp 0.7 indexes struct fields and enum variants and renames only the
right binding: .member / ::Variant / field-init, without clobbering locals.
- Member scan in analyzeFile; access kinds bare/dot/colon/field-init
- classifyRenameTarget: local | member | global
- smoke_lsp_rename_deep + test-lsp wiring
Track locals moved by value into struct fields, let bindings, or return
values so Array/Drop types are not freed while still owned by the target.
- hir_lower: movedOutLocals + markMovedOutFromAst + shouldSkipDrop
- Nexus: drop zeroing workaround; free headers after each request
- examples/move_field.bux regression for Box { items: arr }
Session 36: prevent UAF when Array is moved into a struct field (Nexus
headers), align selfhost cc flags with bootstrap debug/release, and add
workspace/symbol search to bux-lsp 0.6.
- Parser: zero headers after embedding so auto-drop is a no-op
- Request_WantsKeepAlive uses RequestHeader_Get again safely
- Selfhost: default -O0 -g; --release -O2 -DNDEBUG; BUX_CFLAGS
- LSP: workspace/symbol + smoke; version 0.6.0
Add workspace-aware Find All References and Rename for scoped locals and
globals, plus registry/apps/dwarf smokes in the default test target.
- bux-lsp: textDocument/references, prepareRename, rename
- make test-lsp runs smoke_lsp_rename; make test includes registry/dwarf/apps
Ship the QUALITY_PLAN stretch from ownership through ecosystem: C.1
lifetime elision (bootstrap + selfhost), bux fmt/test/doc CI hooks,
stdlib goldens, package registry (bux search/add), and LSP 0.4
position-sensitive locals with inferred let types. Full-tree format
pass plus Map/Set remove double-free fix.
Multi-field variants use Enum_Variant_Payload nested types (avoids tag name clash).
Sema resolves data.Variant.Variant_i; enum field types fully resolve tuples.
Selfhost parses full type exprs in enum payloads; emit structs/tuples before enums.
Example: examples/nested_patterns.bux (Pair::Two, Box::Val((a,c)), Shape::Dot).
Blocks can yield a value: last expression statement is the result.
Match arms accept block bodies, so multi-statement arms work:
match n {
1 => { let a = 10; a + 1 },
_ => 0
}
Bootstrap: lowerBlock(asExpr) lifts the trailing skExpr. Selfhost: parse
{...} as ekBlock, emit __blk_N yield temps (retTypeKind -2), and treat
only non-empty strValue as match/block yield. Nested enum/struct pattern
bindings recurse in both compilers.
Example: match_block.bux. Selfhost-loop remains binary-identical.
Support destructuring in match arms:
- Tuple: (a, b) binds subject._0 / _1
- Struct: Point { x: px, y: py } and shorthand Point { x, y }
Bootstrap: matchPatternBindings for pkTuple/pkStruct; register local
tuple typedefs from function bodies. Selfhost: parse, Sema_BindPattern,
Lcx_PatternBindings with scope defines. Fix operator-overload path that
crashed when typeName was null after pattern binds.
Example: examples/struct_tuple_pat.bux. Selfhost-loop IDENTICAL.
Sessions 10–12 from QUALITY_PLAN:
- Pattern payload bindings (Some(value) => value) in bootstrap and selfhost
- Empty-param closures via || (tkPipePipe) with loop/return bodies
- Expression-form match: let x = match …; newline before arms
- f"…" string interpolation desugared to String_Concat + conversions
- Lexer preserves \{ \} for literal braces in f-strings
- Bootstrap fix: f"plain" strips the f prefix after escape processing
- Examples: pattern_matching, closure_control, match_let, string_interp
Selfhost-loop remains binary-identical; all examples and error goldens pass.
Add int-specialized higher-order Iter helpers that accept fat function
pointers, plus an example using named funcs and capturing closures.
Fix selfhost C backend pointer field access and Array Push indexing.
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.
- Rewrite apps/nexus with modular architecture:
Config, Http, Errors, Parser, Router, Handlers, Server, Main
- Use algebraic enums for ParseResult/FileResult/HttpError
- Thread-pool server via Channel<ConnectionTask> and spawn
- Fix C backend type ordering for generic struct instances
(Array_T, Iter_T) and algebraic enum struct payloads
- Collect Slice_T types from struct fields and enum payloads
- Fix match lowering for simple enums (direct value compare)
- Resolve match expression return type from first arm
- Infer element type for for-in over Array<UserStruct>
- Preserve generic type args in field access resolution
- Add fflush to PrintLine/Print for immediate server logs
- Add modern_features golden regression test
- Regenerate golden expected.c files
- Add -Wl,--build-id=none to C compilation flags (removes non-deterministic build ID)
- Update Makefile selfhost-loop to strip debug info before ELF comparison
- Bootstrap compiler and selfhost compiler both deterministic
Add golden tests for: structs, generics, algebraic_enums, enums,
methods, strings. Each test captures the expected C output from the
bootstrap compiler for regression detection.
Also remove leftover 'PARSER FIX V2 ACTIVE' debug print from parser.bux.
- Makefile: new targets `test-golden` and `selfhost-loop`
- selfhost-loop verifies C codegen determinism (2-pass bootstrap)
- test-golden compares C output against expected.c golden files
- Updated clean-all to clean new build dirs
- tests/golden/hello/: first golden test (hello world)
- src/sema.bux:
- Fix: import stubs only registered if symbol doesn't already exist
- Improve: error message now includes identifier name
- Fix lirValToC crash on lvkInt in hStore raw C emission
- Add hAlloca handling to lowerExpr (returns &name, avoids unhandled fallback)
- Fix nested comment syntax in unhandled expr fallback
- Rewrite buildLval to handle hIndexPtr and nested hFieldPtr/hArrowField
so assignments like arr[i].field = val emit direct C lvalues
- Make &&/|| temporaries unique (__and_tmp_N/__or_tmp_N) to avoid
duplicate declarations in the same function
- Selfhost null-deref fix in sema.bux (unchained nested conditions)
The old findGenericCalls second-pass only looked in non-generic functions
and generated unresolved instances like Array_Get_T when generic funcs
called other generic funcs. Removed it entirely.
lowerExpr for ekCall now invokes generateMethodInstance directly for
both explicit (ekGenericCall) and inferred generic calls. This ensures
concrete instantiations are generated on-demand with correct typeSubst.
Also added guard in resolveTypeExpr/substituteType to skip emitting C
struct definitions for unresolved type parameters (e.g. Array<T> inside
a generic function body before monomorphization).
feat(std): add Std::Iter module
- Array_Iter, Iter_Next, Iter_HasNext, Iter_Peek, Iter_Reset
- Iter_Pos, Iter_Len, Iter_Count, Iter_Skip, Iter_Take
docs: document Std::Iter in Stdlib.md
examples: add iter.bux example
tests: add _test_array regression test
- Added exprSpawnAsync flag to AST ekSpawn
- Sema checks if callee is async and sets the flag
- HIR hSpawn carries spawnAsync flag
- C backend uses bux_task_spawn for non-async (OS threads) and bux_async_spawn for async (coroutines)
- Added concurrency example to test suite
Self-hosted compiler (buxc2):
- Add async/await/spawn tokens, parsing, HIR, lowering, C emission
- Fix pointer type emission (*T -> T*) in C backend
- Fix sizeof(Type) parsing with parentheses
- Fix import ::{...} infinite loop guard
- Fix int64 emission by avoiding else-if chain workaround
- Add debug-free cli and hir_lower
Bootstrap compiler (Nim):
- Fix critical else-if lowering bug in hir_lower.nim:
when both elseIfs and else block exist, elseIfs were dropped
causing all else-if chains to collapse to if+else only
Runtime:
- Fix bux_async_await memory corruption (don't free in run)
- Add bux_remove_from_ready for safe cleanup
- Fix forward declaration and deduplicate bux_now_ms
Docs & examples:
- Update async.bux example with proper int64 params
- Update README, LanguageRef, Stdlib, PLAN for async features
- Mark Phase 7.10 bootstrap loop as completed
All 27 examples pass. buxc2 check/build work on all examples.
- Add generic struct instantiation (Box<int>, Pair<T,U>) in HIR lowering
- Fix tkUnknown/tkNamed/tkTypeParam ambiguity in sema.nim (qualify with TypeKind)
- Add generics_struct example
- Update Makefile with new example
Add standard library modules:
- Std::String: strlen, strcmp, concat, copy, starts_with wrappers
- Std::Map: linear-probing hash map with String keys, int values
Add error handling:
- Result and Option algebraic enum examples
- ? try operator for automatic error propagation in HIR lowering
Compiler bugfixes:
- Fix sizeof() for user-defined structs (new hSizeOf HIR node)
- Fix HIR type lowering for char8, bool8, int8, uint8, etc.
- Fix let statement lowering for pointer types (*char8 → int* bug)
- Fix PrintInt ABI mismatch (int64_t → int in io.c)
- Fix Makefile test bug (_test_tmp_pkg already exists)
Documentation:
- Rewrite README.md with features, examples, project structure
- Add docs/LanguageRef.md — complete language reference
- Add docs/Stdlib.md — standard library documentation
- Add docs/BuildAndTest.md — build and test guide
New examples: strings, map, result_option, try_operator (13 total)
- C backend: strip c8/c16/c32 string prefixes in emitted C
- C backend: resolve imports to fully-qualified names (Std_Io_PrintLine)
- Parser: fix infinite loop on < in comparisons vs generic calls
- Parser: fix enum patterns without parens (Option::None)
- Parser: fix match expressions inside blocks
- Sema: extract pattern bindings for match arms
- HIR: lower match expressions to if-else chains with enum tag checks
- HIR/C backend: support block expressions as function return values
- Makefile: add integration tests for all 9 examples
- Add pattern_matching.bux example