Desugar `is` to tag/value equality in bootstrap and selfhost so LIR
no longer drops hIs as false. Resolve monomorphized Result/Option type
names for `?` (_Tag/_Data). Call bux_exit(1) after Unwrap panic messages.
Add is_operator example and document follow-up fixes.
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.
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 }
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.
Lower match to if-else for literals, ranges, enum tags, and wildcards.
Fix bootstrap literal arms that always matched; port real arm AST/parser
and Lcx_LowerMatch to selfhost with last-expression return. Expand
pattern_matching example and add parse/use-after-move/double-mut golden
diagnostics. Selfhost-loop remains binary-identical.
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.
- sema: range bounds now accept compatible integer types (e.g. int..uint)
instead of requiring exact type equality.
- hir_lower: derive loop variable type from the common range type.
- boko-framework: replace manual while loops with for loops in Query_Parse,
Request_Parse, Path_Match and App_Run.
- 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
- Export typeToTypeExpr from sema and preserve generic type args
- Derive loop variable type from collection element type in sema
- Substitute generic struct type params on field access
- Add getCollectionElementTypeExpr helper in hir_lower
- Replace placeholder collection for-in lowering
- Add Array/Iter lowering: Array_Iter_T / Iter_HasNext_T / Iter_Next_T
- Add Channel lowering: Channel_Recv_Ok_T loop
- Register loop variable in varTypeExprs before body lowering
Fixes _test_forin_stdlib, _test_forin_channel, _test_generic_trait, _test_import, _test_mono
- Preserve type args on tkNamed in resolveType
- Resolve explicit generic call return types with concrete substitutions
- Substitute method type params when looking up operator_index_get
- Skip strict arg checks for generic function calls (deferred to inference)
- Fix generic struct monomorphization when no caller substitution map exists
- Fix parameter varTypeExprs ordering so pointer params are visible in bodies
Fixes _test_drop_trait and _test_checked_index
Implement MVP closures — anonymous functions without captures.
Syntax:
|a: int, b: int| -> int { return a + b; }
Changes:
- ast.bux + ast.nim: add ekClosure AST node
- parser.bux + parser.nim: parse |params| -> Ret { body }
- sema.bux + sema.nim: type-check closure params/body, return tyFunc
- hir_lower.bux + hir_lower.nim: generate __closure_N function + hAddrOf
- lir_c_backend.nim: fix function-pointer variable declaration (cParamDecl)
- C backend: closures compile to global functions with unique names
Test: _test_closure/src/Main.bux
- Closure as variable
- Closure passed to higher-order function
- Address of named function as function pointer
Both bootstrap and selfhost compilers build and pass the test.
- Add tekFunc AST node and parser support for func(Params) -> Ret
- Add tkFunc type resolution in sema and hir_lower
- Add &FuncName address-taking yielding tkMutRef(tkFunc)
- Fix C emission: function pointer params use Ret (*name)(Params) syntax
via cParamDecl helper that embeds the name inside (*)
- Fix forward declarations and temp declarations for function pointers
- Add funcPtrTypes table in C backend so &Fn temps get proper type
- Add _test_funcptr integration test
- Add operatorMethodName mapping (tkPlus -> operator_add, etc.)
- Add tryLowerOperatorCall / tryLowerIndexCall in HIR lowerer
- Modify ekBinary lowering to check method table before builtins
- Modify ekAssign lowering to detect ekIndex target and emit
operator_index_set method call when available
- Add sema type-checking for operator overloads in ekBinary
and ekIndex paths (method-table lookup before builtin rules)
- Fix sema compile errors: minfo.params[N].typ -> minfo.params[N]
- Fix hir_lower forward decl ordering for resolveExprType
- Update golden test expected.c files for current C backend
- Update ROADMAP.md and PHASE8_STRATEGY.md status
- Add syntax
- Desugars to if-else chain in HIR lowering (both compilers)
- No new HIR/C backend nodes needed — reuses hIf/hBinary/hBlock
- Supports integer, char, and enum tag dispatch
- Case body can be single statement (no braces required)
- Add statement for function-level deferred execution
- Deferred expressions run in LIFO order on function exit (return or implicit)
- Bootstrap: desugar defers in hir_lower.nim (inject before return + end of func)
- Selfhost: emit defers in c_backend.bux via CEmitter defer stack
- Both: add tkDefer token, skDefer AST node, hDefer HIR node
- Parser, lexer, sema, token files updated in both bootstrap/ and src/
hir_lower.resolveExprType for ekField now correctly resolves variant
positional/named fields (e.g., r.data.Ok_0, r.data.Err_0) on _Data
union types, matching the existing logic in sema.checkExpr.
This fixes the runtime segfault in examples/algebraic_enums.bux where
the C backend emitted an int temporary for a String field, causing
PrintLine to dereference a garbage pointer.
- Fix bootstrap sema to type simple enum variants as the enum itself
(not _Tag), and .tag access returns the enum type.
- Fix hir_lower to lower simple enum .tag as no-op and Enum{tag:X}
init as X directly.
- Fix sema collectGlobals to register imports AFTER real declarations,
preventing duplicate-symbol errors when stdlib files import symbols
defined in later files (e.g. jwt.bux importing rsa.bux).
- Rewrite lib/crypto/*.bux as single-line to work around bootstrap
parser limitations with multi-line function calls.
- Rename 'pub' -> 'pubBuf' in ed25519.bux and jwt-pitbul/Main.bux
to avoid reserved keyword collision.
- Remove algTag:int workaround from jwt-pitbul/Main.bux; enum
comparisons now type-check without manual casts.
- Update .gitignore to exclude _test_*/ and backup files.
- Delete accidentally-committed _test_array/ directory.
- examples/borrow.bux: working borrow expression example
- tests/borrow_test.nim: add 4 new tests for borrow & @[Shared]
- parser.nim: fix borrow parsing order (& before mut)
- Build verified: example compiles and runs
- 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)
- hir_lower: add isScope=true to lowerBlock; fix resolveExprType for ekIndex,
ekField on monomorphized structs, and ekTry/ekUnwrap tmpVar typing
- lir_lower: add loop label stack for break/continue; pass null arg to
bux_task_spawn when spawn has no arguments
- lir_c_backend: multi-pass type inference for temps; include params in
varTypes; handle lvkTemp in lirLoad; use inferred type in lirAlloca