- @[Release] disables borrow checking and bounds checking in the function
- --release passes -O3 -flto to the C compiler for optimized builds
- Selfhost loop still deterministic
- Auto-drop now only triggers for user-defined types explicitly marked
with @[Drop] on the struct declaration.
- Added move tracking in C backend to skip auto-drop for variables
that have been moved (via let y = x, return x, or assignment).
- Prevents double-free when ownership is transferred.
- Selfhost bootstrap loop verified: C output is deterministic.
- ast.bux: add isDrop field to Decl
- parser.bux: parse @[Drop] attribute and attach to struct Decls
- hir_lower.bux: auto-drop now looks for TypeName_Drop for any type
- Test: _test_drop_user verifies Buffer_Drop is auto-called
- Auto-register func Type_Method(self: T, ...) as methods in sema.
- Add method table lookup for binary operators in sema.bux ekBinary.
- Add method table lookup for operator_index_get in sema.bux ekIndex.
- Add HIR lowering for binary operators to method calls in hir_lower.bux.
- Add HIR lowering for operator_index_get/set in hir_lower.bux.
- Set expr.refType for overloaded operators so chained ops work.
- Fix hir_lower.bux to recognize Array_int/Iter_string etc. in for-in loops
by checking Array_/Iter_ prefix outside the empty-elemTypeName branch.
- Update all golden expected.c files to include duplicate bux_bounds_check
declaration (matches actual C codegen).
- Remove duplicate Drop trait item from ROADMAP.md.
In @[Checked] functions, variables of type Array<T> automatically get
a defer Array_Free_T(&var) injected at declaration site. This ensures
Array values are freed when they go out of scope, preventing leaks.
Implementation:
- HIR lowering detects Array_<T> types in skLet statements
- Generates Array_Free_T generic instance if needed
- Builds synthetic defer node: defer Array_Free_T(&var)
- Wraps let+defer in hBlock for proper statement chaining
Also adds checkedFunc flag to HirFunc and CEmitter for future use.
- cli: buxc2 build now delegates to Cli_BuildProject for src/Main.bux,
enabling stdlib merging (Array_Iter, Iter_HasNext, etc. available)
- sema: set expr.refType on ekCall from function return type
(needed for for-loop type extraction from MakeArr()-style expressions)
- hir_lower: remove ekIdent restriction on collection-based for loops
- supports arbitrary expressions: for x in MakeArr() { ... }
- creates temp variable __tmp_coll_N for non-identifier iterators
- generates proper Array_T struct instances for temp variables
- Test: for x in MakeArr() sums [10,20,30] → 60
- Selfhost loop: C output IDENTICAL
- Fix Fmt_Format name conflict between lib/Fmt.bux and src/fmt.bux
by renaming selfhost formatter function to Fmt_FormatSource.
- Fix collection-based for-in loops to handle already-monomorphized
types like Array_int and Iter_string (typeArgCount=0 cases).
- Fix ekSizeOf and ekCast in HIR lowering to apply Lcx_SubstituteType
during generic monomorphization, so sizeof(T) and *T casts emit
correct concrete types in C output.
- Fix sema to infer stmt.refStmtType from initializer expression
when no explicit type annotation is given, ensuring C backend
emits correct pointer types for let data = ... as *T.
- Fix nested Lcx_GenerateStructInstance overwriting parent slot by
incrementing structCount BEFORE field processing
- Fix Lcx_LowerModule to skip generic structs from hm.structs (was missing
continue due to bootstrap compiler codegen limitation)
- Fix C backend to forward-declare ALL structs at top, removing second
generic-only forward declaration section that came too late
- Add empty-name guard in CBE_EmitStructDef
- Import system: parser supports ::* glob imports, sema two-pass resolution
- Add on-demand generic function/struct monomorphization in HIR lower
- Lcx_SubstituteType: substitute type params and mangle names (e.g. Array<int> -> Array_int)
- Lcx_GenerateFuncInstance: clone generic func with active substitution
- Lcx_GenerateStructInstance: create concrete struct definitions
- Detect generic calls (ekCall) and struct inits (ekStructInit)
- Parser: propagate generic type args from ident to ekStructInit node
- Fix duplicate HIR constant: hIndexPtr and hCall both had value 18,
causing index expressions to emit as comma expressions in C backend
- Implement collection-based for-in desugaring:
for x in arr { body } -> __iter = Array_Iter_T(&arr);
while Iter_HasNext_T(&__iter) { x = Iter_Next_T(&__iter); body }
Selfhost loop remains deterministic. All golden tests and examples pass.
- Parser: add parseRange for selfhost (.. / ..=)
- Sema: determine loop variable type from range bounds
- HIR Lower: desugar range for-in to while loop with counter
- Bootstrap sema: fix range-based for variable type (was unknown)
- Selfhost loop remains deterministic
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 tekRef and tekMutRef to TypeExpr enum (ast.bux)
- Parse &T and &mut T in parserParseType, before *T handling (parser.bux)
- Map tekRef/tekMutRef to tyPointer in HIR lowering (hir_lower.bux)
- Both emit as T* in C backend (same as raw pointer)
- Borrow checker rejects write-through-pointer in @[Checked] functions
for all pointer types (safe default)
- Remove DEBUG prints from c_backend.bux, hir_lower.bux, lexer.bux, parser.bux
- Remove HACK for stray } in parserParseFuncDecl (no longer needed after
Decl refactor in 4a86009)
- Clean selfhost check/build output
- Replace Decl's 256 inline struct fields with dynamic fields: *StructField
array to avoid parser field limit truncation and name shifts.
- Update parser.bux and hir_lower.bux to use decl.fields[i].
- Fix uninitialized Symbol.refType in three stack-allocated Symbol sites:
loopSym (for-loop iterator), vSym (enum variants), and HIR param sym.
Garbage refType values (e.g. 0xFF) were leaking into scope tables,
later copied to expr->refType, causing SIGSEGV in Lcx_LowerExpr.
- Add tekFunc AST node and TypeExprList linked list for params
- Parse func(T, U) -> R syntax in parser.bux
- Resolve tekFunc to tyFunc in sema.bux
- Track original TypeExpr via Symbol.refType for params/lets/consts/funcs
- Build C function-pointer type names in hir_lower.bux (Ret (*)(Params))
- Lower indirect calls through function-typed values as hCallIndirect
- Add CBE_CParamDecl helper in c_backend.bux to embed name inside (*)
- Emit hCallIndirect and function-pointer variable declarations
- _test_funcptr now builds and runs with selfhost buxc2
- 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/
The selfhost parser did not skip tkNewLine tokens inside expression parsing,
causing multi-line expressions (e.g. if conditions spanning lines with ||)
to be truncated. When parserParseBinaryPrec hit a newline it treated it as
an invalid primary, returning a malformed literal and leaving p.pos at the
newline. parserParseBlock then failed to find '{' and its depth-counter
fallback consumed far too many tokens, causing subsequent function bodies
to be parsed into the wrong AST nodes.
Fix: add newline skipping in parserParsePrimary, parserParseUnary, and
parserParseBinaryPrec, matching the bootstrap parser's skipNewlines() calls
in parseAnd/parseOr.
Also complete the variant cap raise from 8->9 in src/sema.bux (was already
done in ast.bux, parser.bux, hir_lower.bux).
- ast.bux: Decl expanded with field0..field255, variant0..7, param0..8
- parser.bux: add parserParseUnary for correct unary precedence; handle tkDiscard statements; allow var without initializer (matching bootstrap); add diagCount bounds check in parserEmitDiag
- hir.bux: HirParam changed to pointers
- hir_lower.bux: full field chains for struct lowering
- c_backend.bux: hardened -> vs . field access; null checks in CBE_GetExprTypeName
- cli.bux: add -lcrypto to linker