- 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/
- Add String_IsNull and String_Offset wrappers in lib/String.bux
- Add bux_str_is_null and bux_str_offset runtime functions in rt/runtime.c
- Update String_Replace to use String_IsNull instead of String_Len(pos)==0
- Replace pointer-to-uint casts (as uint == 0, pointer arithmetic) across apps/
- Parser newline skipping fixes in src/parser.bux
bux_sb_build returned sb->buf and then bux_sb_free freed it,
causing dangling pointers in all callers of StringBuilder_Build
followed by StringBuilder_Free (e.g. JsonParser_ParseString, Fmt).
Fix: bux_sb_build now detaches the buffer (sets sb->buf = NULL)
before returning it, so bux_sb_free only frees the sb struct.
This transfers buffer ownership to the caller.
Backtick strings were emitted directly into C code without
stripping the backticks or escaping the content, causing C syntax errors.
Fix: detect backtick-wrapped literals in CBE_EmitExpr, strip
the backticks, escape inner content, and wrap in double quotes.
Simple enums were emitted as plain C enums, but the rest of the codegen
(and source code) expected them to have a .tag field like algebraic enums.
This caused C compilation errors:
- 'request for member tag in something not a structure or union'
- 'field name not in record or union initializer'
Fix: always emit the _Tag typedef + struct wrapper for every enum.
For simple enums, the struct only contains the tag (no _Data union).
For algebraic enums, keep the existing _Data union + struct behavior.
This matches the bootstrap compiler's enum codegen.
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).
parserParseImportDecl now skips tkNewLine tokens inside {..} blocks,
matching the bootstrap parser behavior. This fixes parsing of imports
with names on separate lines, e.g.:
import Std::String::{
String_Eq,
String_Len
};
Previously the parser failed because it expected tkIdent immediately
after { but encountered tkNewLine instead.
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.
Parser would hang (infinite loop) when encountering newline tokens
inside certain constructs because expect() returns without advancing
position when the expected token doesn't match.
Fixed 5 places in parseBaseType, parsePrimaryPattern, parseTypeParams,
parseParamList, and parseUseDecl by adding newline-skipping at the
start of each iteration.
Verified: compiler no longer hangs/crashes on all 3 real-world apps
from apps/ (boko-framework, jwt-pitbul, nexus).
- README: bump version to v0.4.0, add selfhost loop & borrow/shared
- Stdlib.md: update sections 1-4, add String_Chars, FromBool, Fmt, Iter
- BuildAndTest.md: add make selfhost-loop and make test-golden targets
- Standard library list updated to all 23 modules
- 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
This workaround consumes a stray } that parserParseBlock sometimes leaves
behind, which was causing the module handler to exit early. With this fix,
the selfhost compiler (buxc2) can now compile the entire src/ project.
- buxc2 project build: 491 user + 310 stdlib = 801 decls, no sema errors
- make selfhost-loop: builds and runs both passes
- C compilation succeeds, resulting binary works
- Cli_BuildProject now appends declarations (preserving original file order)
instead of prepending (which reversed order)
- Added per-file declaration count debug output
- This makes merge order match Nim bootstrap behavior
- 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
- 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
- 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
- 42 LIR instructions in bootstrap/lir.nim
- HIR→LIR lowering in bootstrap/lir_lower.nim
- LIR→C emission with full struct/enum/vtable support
- All 22 examples + 5 Nim unit tests passing
- Updated README status and backend description