Commit Graph

217 Commits

Author SHA1 Message Date
dimgigov 85d15cd16d docs: add source location error messages implementation plan 2026-06-10 20:00:09 +03:00
dimgigov de3ac76581 docs: add source location error messages design document 2026-06-10 19:56:55 +03:00
dimgigov 2824d25369 test: add green thread integration test
Also fix runtime scheduler bugs:
- g_task_creating was thread-local but set on main thread and read on worker
- g_scheduler_context was global shared by all workers instead of per-thread
2026-06-10 19:48:47 +03:00
dimgigov 9cd0580832 feat(task): add full green thread API (Init, Wait, Yield, CurrentId, Shutdown) 2026-06-10 19:45:24 +03:00
dimgigov 9e547f123a fix(scheduler): make Task_Sleep yield instead of block (MVP) 2026-06-10 19:44:55 +03:00
dimgigov 211a811f32 feat(scheduler): implement green thread scheduler with work-stealing 2026-06-10 19:43:31 +03:00
dimgigov 4456bb00af docs: add green threads implementation plan 2026-06-10 19:38:24 +03:00
dimgigov 6a0a0425dd docs: add green threads / task scheduler design document 2026-06-10 19:33:53 +03:00
dimgigov 9e515c157d feat(pkg): add basic package manager (add, remove, fetch, build deps)
- manifest.bux: parse [dependencies] section with up to 8 deps
- manifest.bux: Manifest_AddDep, Manifest_RemoveDep, Manifest_ToString
- cli.bux: bux add <name> <url> — adds dependency to bux.toml
- cli.bux: bux remove <name> — removes dependency from bux.toml
- cli.bux: bux fetch — git clone/pull dependencies into deps/
- cli.bux: Cli_BuildProject now merges deps/<name>/src/*.bux before user code
- Selfhost bootstrap loop verified: C output deterministic ✓
2026-06-10 19:18:36 +03:00
dimgigov 8f8708c5df feat(drop): enforce @[Drop] attribute and add basic move semantics
- 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.
2026-06-10 19:08:15 +03:00
dimgigov 7392013301 docs: add Phase 8.7 — Optimization & Release Mode to PLAN.md
- @[Release] attribute for zero-cost abstractions
- Auto-drop inline, dead-store elimination, -O3 by default, PGO
- Milestone M15: C-speed benchmarks vs Nim/Crystal
2026-06-10 13:51:10 +03:00
dimgigov 0b887b92d3 selfhost: for-in support for Channel<T>; fix break/continue C codegen
- lib/Channel.bux: add Channel_Recv_Ok<T> for use in for-in desugaring
- hir_lower.bux: Channel for-in desugars to while+recv_ok pattern
- c_backend.bux: emit 'break;' / 'continue;' with semicolon, fix missing
  semicolon when break/continue inside if-block
- bootstrap/hir_lower.nim: skip generic methods in vtable generation to
  avoid referencing non-existent monomorphized C functions
2026-06-10 13:46:06 +03:00
dimgigov 7d6cf7f511 selfhost: add lib/Drop.bux with interface Drop; extend methods visible in scope
- lib/Drop.bux: interface Drop { func Drop(self: *Self); }
- sema.bux: define TypeName_MethodName in scope for impl block methods
  so auto-drop (Lcx_BuildAutoDropFree) can find Drop implementations
  via extend Type for Drop, not just @[Drop] or standalone functions
- Verified: extend Buffer for Drop auto-calls Buffer_Drop in @[Checked]
2026-06-10 13:37:55 +03:00
dimgigov 0a41ce85f4 selfhost: add @[Drop] attribute for user-defined structs
- 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
2026-06-10 13:32:40 +03:00
dimgigov d6f0a30948 selfhost: add *_Drop wrappers to stdlib types; auto-drop uses _Drop instead of _Free
- Array.bux, Channel.bux, Set.bux, Map.bux: add *_Drop<T> delegating to *_Free
- hir_lower.bux: Lcx_BuildAutoDropFree searches for _Drop suffix instead of _Free
- Skip direct lowering of generic functions (only monomorphized instances)
2026-06-10 13:25:11 +03:00
dimgigov a2236de69a feat(selfhost): add operator overloading support (+,-,==,[], etc.)
- 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.
2026-06-10 13:11:46 +03:00
dimgigov a4e410fb30 fix(selfhost): for-in with monomorphized Array/Iter types + golden test updates + ROADMAP cleanup
- 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.
2026-06-10 12:57:53 +03:00
dimgigov 51bd3c172b Add Slice<T> generic struct support and fix C backend generic filtering
- Add lib/Slice.bux with Slice<T> generic struct
- Fix C backend to recognize Slice/Slice* as generic types
- Use var instead of let for uninitialized Slice<T> locals
- Selfhost loop passes, tests pass
2026-06-10 12:03:31 +03:00
dimgigov 3a7b4bd5c1 selfhost: extend auto-Drop to Channel<T>, Set<T>, Map<K,V>
In @[Checked] functions, variables of type Channel<T>, Set<T>, and
Map<K,V> now automatically get defer Free_T(&var) injected.

- Added Lcx_BuildAutoDropFree helper that matches typeName prefix
  and generates the appropriate Free instance:
  - Array_<T>  → Array_Free_<T>
  - Channel_<T> → Channel_Free_<T>
  - Set_<T>    → Set_Free_<T>
  - Map_<K>_<V> → Map_Free_<K>_<V>

Selfhost loop passes, C output deterministic.
2026-06-10 11:47:50 +03:00
dimgigov a099999e02 selfhost: auto-Drop for Array<T> in @[Checked] functions
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.
2026-06-10 11:40:11 +03:00
dimgigov 5eec4328f3 docs: update ROADMAP and PHASE8 with completed features
Mark as done:
- for x in collection iterator loops
- Trait bounds (T: Comparable)
- CTFE (compile-time const evaluation)
- Selfhost bootstrap loop (deterministic C output)
- Implicit generic type argument inference
2026-06-10 11:21:04 +03:00
dimgigov c7d4c87fcf selfhost: basic CTFE — compile-time const expression evaluator
Evaluate const declarations at compile time:
- Arithmetic: +, -, *, /, %
- Comparisons: <, <=, >, >=, ==, !=
- Bitwise: &, |, ^, <<, >>
- Logical: &&, ||
- Unary: -, !, ~
- Ternary: cond ? a : b
- Cast: (T)expr (evaluates operand)
- Cross-const references: const C = A + B

Uses multi-pass evaluation to handle forward references
(caused by parser push-front ordering).
2026-06-10 11:11:52 +03:00
dimgigov d70ccba5ca selfhost: implicit generic type argument inference for Array/Iter stdlib functions
- sema: add Sema_InferGenericArg + Sema_ExtractElemType helpers
- Infers T from first argument's collection type:
  - Array_Push(&arr, 10) → Array_Push_int (from &arr's Array<int> type)
  - Iter_HasNext(&it) → Iter_HasNext_int (from &it's Iter<int> type)
- Supports both explicit generic types (Array<int>) and mangled types (Array_int)
- Works with reference expressions (&x) by unwrapping to x's type
- Selfhost loop: C output IDENTICAL
2026-06-10 10:26:08 +03:00
dimgigov 01677001c3 selfhost: for x in collection works with non-identifier expressions + buxc2 build merges stdlib
- 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
2026-06-10 10:20:16 +03:00
dimgigov bb84693acb selfhost: fix extend-for method linked list + trait bounds check before indirect call return
- parser: extend-for only linked first 2 methods; now uses lastMethod pointer
- sema: trait bounds checking was after indirect-call early return (tyFunc path),
  so Max<Circle>(...) skipped bounds check when callee had tekFunc refType.
  Moved bounds check before both indirect/direct call returns.
- Negative test: Circle without Comparable impl now correctly errors.
- Selfhost loop: C output IDENTICAL.
2026-06-10 09:02:22 +03:00
dimgigov f63cbd1bf0 selfhost: trait bounds parsing, sema checks, and generic monomorphization fix
- AST: add typeParam0Bound/typeParam1Bound to Decl, strValue2 to dkImpl
- Parser: parse <T: Trait> bounds, Self type in interfaces, extend-for blocks
- Sema: add interfaceTable/methodTable, Sema_CheckTraitBounds, Sema_TypeImplements
- HIR lower: two-pass decl iteration — collect generic funcs before lowering bodies
  Fixes Max<Circle>(...) not generating Max_Circle when caller precedes callee
- C backend: skip generic funcs in emission (only emit monomorphized instances)
- Array.bux: fix for-loop over monomorphized Array types
- All debug prints removed; selfhost loop passes (C output IDENTICAL)
2026-06-10 08:48:10 +03:00
dimgigov 499b389ba8 fix(selfhost): collection-based for-in with Std::Array + monomorphization fixes
- 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.
2026-06-10 01:15:21 +03:00
dimgigov 632fa1535c fix(test): update wrong-args error message expectation 2026-06-10 00:28:18 +03:00
dimgigov 40bcbeb710 Fix generic struct monomorphization and C output for imports
- 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
2026-06-09 23:33:44 +03:00
dimgigov b36df0f5b7 feat(selfhost): generic monomorphization + collection-based for-in loops
- 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.
2026-06-09 22:33:36 +03:00
dimgigov b3141dbcd5 docs: update ROADMAP + PHASE8 for for-in loops
- Mark range-based for-in as done
- Note collection-based for-in blocked by generic monomorphization
2026-06-09 21:55:40 +03:00
dimgigov 74db8a5790 feat: for-in range loops in selfhost + bootstrap
- 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
2026-06-09 21:53:12 +03:00
dimgigov 6414ef236b docs: update ROADMAP and PHASE8 for closures with captures 2026-06-09 21:23:58 +03:00
dimgigov 9b473c667c closures with captures: env struct + global instance + body rewriting
- AST: captureCount + captureName0..7 + captureType0..7 in Expr
- Sema: Scope_LookupUpTo + closureScope for capture analysis
- HIR Lower: env struct generation, capture assignments in skLet,
  body rewriting (ekIdent -> hFieldAccess on env instance)
- C Backend: env struct def + global instance emission for closures
- Bootstrap: full capture support in sema, hir_lower, lir_lower, lir_c_backend
- Selfhost loop remains deterministic
2026-06-09 21:23:05 +03:00
dimgigov ba54aa240e docs: update ROADMAP and LanguageRef with closures
- Mark capture-less closures as  Done in ROADMAP
- Add closure syntax examples to LanguageRef.md Functions section
- Update PHASE8_STRATEGY.md Milestone A with closures
2026-06-09 20:25:34 +03:00
dimgigov c83f6d5994 feat: capture-less anonymous functions (closures)
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.
2026-06-09 20:24:10 +03:00
dimgigov 34504d1647 docs: sync all docs with recent features
Updated documentation to reflect changes from the last 2 days:

ROADMAP.md:
- Mark string interpolation, named/default params, bux fmt/test/new/init,
  and basic borrow checker as  Done
- Update Recommended Order (next: closures)

PHASE8_STRATEGY.md:
- Update date, achievements, and milestone statuses
- Borrow checker is now  working in selfhost
- CTFE, LSP, formatter, test runner marked done where applicable

LanguageRef.md:
- Add defer, switch/case, string interpolation (f"...")
- Add &T, &mut T, own T to composite types
- Add named/default parameters and operator overloading sections
- Expand @[Checked] rules with double-mut-borrow and use-after-move
- Update keywords and operators

STRATEGY.md:
- Update date and version (0.3.0 selfhost)
- Mark 8.2 borrow checker, 8.4 CTFE, 8.7 LSP as 

BuildAndTest.md:
- Add bux init, bux fmt, bux test commands
- Expand test sections with golden tests and Std::Test
2026-06-09 19:19:53 +03:00
dimgigov 079b76ae71 feat(selfhost): add 'bux fmt' code formatter
Line-based indentation formatter that:
- Adjusts indentation based on { } brace depth (4 spaces)
- Preserves original line structure and comments
- Skips braces inside string/char literals and // comments
- Handles } at line start and mixed brace lines
- 'bux fmt <file>' formats a single file
- 'bux fmt <dir>' formats all .bux files in directory
2026-06-09 17:48:20 +03:00
dimgigov 3ce7ba51d2 feat(selfhost): use-after-move tracking in @[Checked] functions
- Add inline movedName0..7 fields to Sema (avoids dynamic allocation issues)
- Sema_AddMoved: track variable moves from let/var init expressions
- Sema_IsMoved: check if variable was moved before use
- Sema_RemoveMoved: clear moved status on reinitialization (x = value)
- Report 'use of moved value' error for moved variable access
2026-06-09 17:40:20 +03:00
dimgigov 41c0fb1d6f feat(selfhost): double mutable borrow detection in @[Checked] functions
Detect when the same variable is passed as &mut argument twice
in a single function call (e.g. Swap(&x, &x)) inside checked functions.
Matches bootstrap sema.nim behavior (lines 1078-1089).
2026-06-09 17:32:21 +03:00
dimgigov f809827bea feat(selfhost): add &T (shared ref) and &mut T (mutable ref) type syntax
- 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)
2026-06-09 17:30:19 +03:00
dimgigov 81281cbb11 feat(selfhost): @[Checked] borrow checker — basic write-through-ptr detection
- Add isChecked field to Decl struct (ast.bux)
- Parse @[Checked] attribute in parserParseDecl (parser.bux)
- Add checkedFunc flag and movedVars to Sema struct (sema.bux)
- Enable borrow checking per-function in Sema_Analyze
- Reject assignment through raw pointer (*T) in @[Checked] functions
- Skip newlines between @[Checked] attribute and the declaration keyword
  to avoid parser seeing the attribute and function as separate decls
2026-06-09 17:25:28 +03:00
dimgigov c14578d9dd feat(selfhost): add 'bux test' command
- 'bux test [dir]' builds the project and runs the resulting binary,
  reporting 'Tests passed' or 'Tests failed (exit code N)'.
- Builds on existing Cli_BuildProject pipeline — test code goes in
  src/ alongside production code; test assertions use lib/Test.bux.
2026-06-09 17:11:31 +03:00
dimgigov 0ac254facc feat(selfhost): add 'new' and 'init' CLI commands
- 'buxc new <name>': creates a new Bux project directory with bux.toml
  and src/Main.bux. Supports both relative names and absolute paths.
- 'buxc init': initializes a Bux project in the current directory.
- Adds extern bux_getcwd() and bux_path_parent() declarations.
- Fix mkdir return value check (bux_mkdir_if_needed returns 0 on success).
- Extract package name from path for absolute path arguments.
2026-06-09 17:09:03 +03:00
dimgigov 392dd64f97 cleanup(selfhost): remove 17 dead functions across 5 files
Remove unused helper functions, factories, accessors, and merge helpers:
- c_backend.bux: CBE_Init, CBE_ClearDefers, CBE_EmitLine, CBE_Build, CBackend_Free
- hir_lower.bux: Lcx_FreshName, Lcx_LowerType, HirLower_Free
- lexer.bux: Lexer_Init, lexIsIdentKind, Lexer_TokenCount, Lexer_GetToken
- parser.bux: parserIsBinaryOp, parserPrevious, parserMergeAddDecl,
  Parser_DiagCount, Parser_Free, Parser_MergeModules
- sema.bux: Sema_TypeName

None of these functions are referenced anywhere in src/.
2026-06-09 16:14:31 +03:00
dimgigov 90e67079f4 cleanup(selfhost): remove unused Print/PrintLine externs + dead debug comments from sema.bux 2026-06-09 15:59:57 +03:00
dimgigov 265bda850d test: expand golden C-codegen tests from 2 to 8 examples
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.
2026-06-09 15:58:44 +03:00
dimgigov 3ed5891de2 fix(selfhost): block scoping for if/while/loop/match bodies
- Create child scope in Sema_CheckBlock for every block, matching
  bootstrap sema.nim behavior (newScope for ekBlock).
- Fixes "var scoping bug in selfhost sema" where variables declared
  with var inside if/while blocks shared parent function scope, causing
  duplicate-definition errors between sibling if/else blocks, and C
  scoping mismatch between user variables and compiled output.
- Remove stale workaround comments from lib/Json.bux (let instead of
  var inside if blocks — no longer needed).
- Update sema.bux TODO comment for type table.
2026-06-09 15:56:16 +03:00
dimgigov 64bd41067a cleanup(selfhost): remove 24 DEBUG prints + stale parser HACK
- 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
2026-06-09 15:48:38 +03:00
dimgigov 4a860095fd fix(selfhost): resolve segfault in buxc2 compiling src/
- 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.
2026-06-09 15:03:45 +03:00