Commit Graph

161 Commits

Author SHA1 Message Date
dimgigov 846c29c6dd examples: add testing example for bux test 2026-06-05 23:06:53 +03:00
dimgigov f02b354e9a feat: bux test command + Std::Test module
- Add 'bux test' CLI command: discovers .bux files in tests/, compiles
  each into a temp package, runs them, reports pass/fail
- Add Std::Test module with Assert, AssertEqInt, AssertTrue,
  AssertFalse, Fail
- Add bux_exit and bux_assert C runtime primitives
- Update README.md and docs/BuildAndTest.md
2026-06-05 22:58:02 +03:00
dimgigov 2a19734c72 docs: update README status to reflect actual project focus
Self-hosted compiler (buxc2) is deprioritized; bootstrap compiler
(buxc, Nim) is the actively maintained and used compiler.
2026-06-05 22:49:27 +03:00
dimgigov 1f64f4707e fix: algebraic enum C backend and sema field type resolution
- Fix sema.nim: use objType.name instead of obj.name for algebraic enum
  tag/data field types (was generating _Tag instead of EnumName_Tag)
- Fix c_backend.nim: emit enum definitions before struct definitions
  to allow structs to reference algebraic enum types
2026-06-05 22:47:37 +03:00
dimgigov 154579b30d feat: String_ToFloat + Json escape sequence support
- Add bux_str_to_float() C runtime wrapper (strtod)
- Add String_ToFloat() in library/std/String.bux
- Update JsonParser_ParseNumber to use String_ToFloat (decimals now work)
- Update JsonParser_ParseString to decode escape sequences (\n, \t, \r, \", \\, \b, \f)
- Fix use-after-free in JsonParser_ParseString: String_Copy before StringBuilder_Free
2026-06-05 22:35:50 +03:00
dimgigov d0de9c2abf feat: Std::Sync — Mutex and RwLock primitives
- Add bux_mutex_* and bux_rwlock_* C runtime functions
- Add library/std/Sync.bux with Mutex and RwLock wrappers
- Add examples/sync.bux — threaded counter with Mutex
- Update docs/Stdlib.md with Sync section and example
- Update README.md feature table
2026-06-05 22:30:44 +03:00
dimgigov 809785711c docs: add missing stdlib modules and update language reference
Stdlib.md:
- Add Std::Task (thread spawn/join/sleep)
- Add Std::Channel (generic channels + wrappers)
- Add Std::Net (TCP sockets)
- Add Std::Json (parser/serializer)
- Add Std::Crypto (SHA-256, HMAC, Base64, random)
- Add Std::Fmt (formatting wrappers)
- Add Std::Math (Sqrt, Pow, Abs, Min, Max)
- Add String_FromFloat to String docs
- Update Future Modules list

LanguageRef.md:
- Add Concurrency section (threads + channels)
- Update Ownership with move semantics and own T

BuildAndTest.md:
- Add libssl-dev/openssl prerequisite note
- Mention -lcrypto auto-linking
2026-06-05 22:19:46 +03:00
dimgigov 96aada2a4e fix: Channel_RecvInt init + add channel example to README
- Initialize result to 0 in Channel_RecvInt/RecvFloat64 to handle closed channel
- Add producer/consumer channel example in examples/channel.bux
- Update README.md with Channels syntax preview
2026-06-05 22:15:56 +03:00
dimgigov a7f96c8e0d Remove temporary _test_borrow2 directory 2026-06-05 21:56:54 +03:00
dimgigov 636c49e9df feat: improve borrow checker — reinitialization, assignment move, return move
- Add isOwn field to Symbol for tracking own T declarations
- Reinitialization after move: assigning to a moved variable removes it from movedVars
- Move tracking in let/var initialization: var b: own Box = a moves a
- Move tracking in assignment: x = y moves y if y is own T
- Move tracking in return: return x moves x if x is own T
- Expand borrow_test.nim to 10 tests (all passing)
2026-06-05 21:56:47 +03:00
dimgigov ce3b4c99f0 Remove temporary _test_crypto directory 2026-06-05 21:34:43 +03:00
dimgigov fe31ddbc4b feat: add Std::Crypto — SHA-256, HMAC-SHA256, Base64, random bytes
- C runtime (OpenSSL): bux_sha256, bux_hmac_sha256, bux_random_bytes,
  bux_base64_encode, bux_base64_decode, bux_bytes_to_hex
- library/std/Crypto.bux: Crypto_Sha256, Crypto_HmacSha256,
  Crypto_HmacSha256Raw, Crypto_RandomBytes, Crypto_Base64Encode,
  Crypto_Base64Decode
- examples/jwt.bux: full JWT creation with HS256 signature
- Link with -lcrypto in C backend
2026-06-05 21:34:37 +03:00
dimgigov fd9abb12be Remove temporary test directories 2026-06-05 21:26:57 +03:00
dimgigov 49264b5d06 feat: add Std::Json — JSON parser and serializer
- JsonValue struct supporting null, bool, number, string, array, object
- Json_Parse(s: String) -> JsonValue: recursive descent parser
- Json_Stringify(v: JsonValue) -> String: recursive serializer
- Access helpers: Json_ObjectGet, Json_ObjectSet, Json_ObjectHas,
  Json_ArrayGet, Json_ArrayPush, Json_ArrayLen, Json_ObjectLen
- Constructors: Json_Null, Json_Bool, Json_Number, Json_String,
  Json_Array, Json_Object
- Type accessors: Json_IsNull, Json_AsBool, Json_AsNumber, Json_AsString
- examples/json.bux: demonstrates parse, access, build programmatically
- Add os_time, process, json to test-examples suite
2026-06-05 21:26:51 +03:00
dimgigov 459e4fb6db Remove temporary _test_fmt directories 2026-06-05 21:05:05 +03:00
dimgigov db9025f3a3 feat: add Std::Fmt — string formatting module
- C runtime: bux_float_to_string() for float64 → String conversion
- String.bux: add String_FromFloat, extern decl for bux_float_to_string
- library/std/Fmt.bux: Fmt_Fmt1, Fmt_Fmt2, Fmt_Fmt3, Fmt_FmtInt, Fmt_FmtInt2,
  Fmt_FmtFloat, Fmt_FmtBool — positional {0}, {1}, {2} placeholders
- Refactor examples to use Fmt:
  factorial.bux, fibonacci.bux, process.bux, os_time.bux
2026-06-05 21:05:00 +03:00
dimgigov 6d4543ead9 Remove temporary _test_net directory 2026-06-05 20:32:27 +03:00
dimgigov ba9f5dfd05 feat: add Std::Net — TCP sockets module
- C runtime: socket(), bind(), listen(), accept(), connect(), send(), recv(), close()
- library/std/Net.bux: Net_Create, Net_Bind, Net_Listen, Net_Accept, Net_Connect,
  Net_Send, Net_Recv, Net_Close, Net_SetReuse, Net_LastError
- examples/tcp_server.bux: echo server on 127.0.0.1:9000
- examples/tcp_client.bux: client that sends 'Hello from Bux!' and prints reply
2026-06-05 20:32:10 +03:00
dimgigov 7b3fa2c423 Remove buxs/ — no Windows support, we build on Linux only 2026-06-05 20:12:51 +03:00
dimgigov 9c6b516453 feat: restructure repo, borrow checker, expanded stdlib
- Reorganize repository to Rust-style layout:
  compiler/bootstrap/  compiler/selfhost/  compiler/tests/
  library/std/  library/runtime/  tests/  tools/
- Add buxs/ Windows-compatible project root
- Add borrow checker tests and implement:
  - Alias analysis (double mutable borrow detection)
  - Use-after-move detection for own T
- Expand standard library:
  - Std::Os: Args, Env, Cwd, Chdir
  - Std::Time: NowMs, NowUs, SleepMs
  - Std::Process: Run, Output
  - Std::Io: PrintInt64 (fixes 32-bit truncation bug)
- Add examples: os_time.bux, process.bux
- Fix PrintInt to use int64_t in C runtime
2026-06-05 20:08:17 +03:00
dimgigov a45a2ecd49 fix: escape sequences in strings, --version/--help, manifest parser, debug cleanup
- Lexer (Nim + Bux): resolve escape sequences (\n, \t, \r, etc) instead of
  keeping raw source text in token. This was the root cause of \n being
  double-escaped to \\n in generated C code.
- Manifest parser (src_bux/manifest.bux): use bux_strlen instead of broken
  String_SplitCount(s, "") hack for string length; fix quote stripping.
- CLI (src_bux/cli.bux): --version/--help now recognized alongside version/help.
- Remove ~30+ debug Print statements from cli, parser, lexer, sema, main.
- Clean up unneeded Print/PrintInt extern declarations.
- _selfhost/src/: synced from src_bux/.
2026-06-05 18:24:59 +03:00
dimgigov a10c49cb16 docs: add bilingual academic textbook (BG/EN) with indexes 2026-06-05 16:30:16 +03:00
dimgigov 3e46e67d48 fix: multi-arg calls, uninitialized symbols, param limit; add banner img; update docs
- Fix segfault from uninitialized Symbol structs in scope/hir_lower/sema
- Fix null ReadFile crash in Cli_MergeFileInto (missing stdlib files)
- Extend function params from 6 to 9 (bux_str_format needs 9 args)
- Add ExprList/HirArgList linked lists for >2 call arguments
- Add banner image to README
- Update docs: C backend is now primary (not QBE)
2026-06-05 15:21:15 +03:00
dimgigov 0c1f230286 selfhost: C backend becomes primary backend; QBE path removed from CLI
Major changes:
- Cli_BuildProject now uses CBackend_Generate instead of QBE SSA generation
- Replaced QBE invocation (vendor/qbe/qbe) with direct cc compilation
- Cli_Build (single-file) now compiles C output with cc including runtime.c/io.c
- Added import-based stdlib merging: only imported Std::* modules are merged,
  eliminating unused generic code from Array/Map/Set/Channel in simple programs

C backend fixes:
- Fixed struct typedef redefinition: struct definitions now use 'struct Name {}'
  instead of 'typedef struct {} Name' to avoid conflicting with forward typedefs
- Added enum support: HirEnum struct, enum emission in C backend, variant
  constants emitted as #define Name_Value
- Added char8 typedef
- Skip generic structs/functions (T/K/V type parameters) in C emission

Sema fixes:
- Fixed Sema_IsNumeric: now correctly recognizes uint, float32, float64
- Fixed return type check: allow pointer compatibility (String <-> *T)

Tested: hello, fibonacci, factorial, enums examples build and run via buxc2
2026-06-05 14:42:18 +03:00
dimgigov 5ae85d5bd9 Phase 2: Fix sema stub — add full function body type checking
- Iterate function body statements and call Sema_CheckStmt on each
- Add Sema_CheckBlock helper for child scope creation in if/while/for/loop blocks
- Extend Sema_CheckStmt to handle all statement kinds: skIf, skWhile, skDoWhile,
  skLoop, skFor, skMatch, skBreak, skContinue, skDecl, skReturn
- Extend Sema_CheckExpr with ekAssign, ekField, ekIndex, ekBlock, ekSelf
- Fix ekCall to resolve return type from function declaration
- Fix ekBinary to handle assignment operators (tkAssign, +=, -=, etc.)
- Add Sema_CollectGlobals handling for dkUse (imports), dkConst, dkEnum variants
- Add tkColonColon path parsing in parser (Color::Red)
- Add decl field to Symbol struct for function/type resolution
- Add Sema_ZeroInitSymbol helper to avoid garbage from uninitialized struct fields
- Fix concurrency.bux missing Task_Join import

All examples now pass buxc2 check. make selfhost succeeds.
2026-06-05 14:07:38 +03:00
dimgigov f0f94f30e1 fix(selfhost): generic struct compilation, explicit generic args, method calls, field access
- parser: add parserIsTypeArgListAhead() for Func<Type>(args) and Type<T> { ... }
- hir_lower: method call desugaring with typeName tracking, self keyword,
  ekField typeName propagation, variable type tracking, strip '*' suffix
  from pointer type names in method calls, fix externFuncs buffer overflow
  (64 -> 256 elements) that corrupted structCount
- qbe_backend: QBE_FindStruct, QBE_FieldOffset, QBE_TypeSize helpers;
  hStructInit field-by-field codegen; hFieldPtr with offset + auto-load;
  hAssign/hStore special case for hFieldPtr (generate pointer, not value);
  fix null as *HirNode -> null as *void for extraData comparisons
2026-06-05 13:07:28 +03:00
dimgigov 291de88506 docs: update README, Stdlib, BuildAndTest, PLAN for new std modules
Added documentation for:
- Std::Fs (DirExists, Mkdir, ListDir)
- Std::Mem (Alloc, Free, MemEq, New)
- Std::Set<T> (Set_New, Set_Add, Set_Has)
- String_Find, String_Replace, String_Format

Updated PLAN.md blockers (all resolved) and self-host status.
Updated README.md project structure and feature table.
Updated BuildAndTest.md with new stdlib modules and path syntax.

Also includes:
- CLI path argument fix (build/check/run accept project path)
- Remove dummyFunc from parser
- Fix String_Replace to use String_Concat instead of buggy str_join2
2026-06-02 18:46:03 +03:00
dimgigov ec4e748584 fix(qbe): use extraData instead of child3 for hIf else-branch
Block lowering overwrites child3 for statement chaining.
Else block is stored in extraData by hir_lower (matches c_backend).
Fixes QBE parse error 'last block misses jump' in if-without-else chains.
2026-06-02 18:07:35 +03:00
dimgigov eb8179b6d0 fix(qbe): any-child terminator check in QBE_IsTerminator for hBlock — QBE SSA now fully valid
- QBE_IsTerminator(hBlock) checks ALL children, not just last
- Removed legacy c_backend.bux and nim_backend.bux from _selfhost/src/
- QBE self-hosting QBE phase: PASSES (SSA valid, assembled to .s)
- Remaining: linker errors from missing String_Eq/StringBuilder in runtime
2026-06-02 13:56:12 +03:00
dimgigov 6cb5528a4d fix(qbe): no-else uses @lEnd target, removed bodyTerminated, brace fix 2026-06-02 13:53:52 +03:00
dimgigov 7efa79d46f fix(qbe): QBE_IsTerminator for hIf+hBlock, smart @lEnd, block-break on terminator 2026-06-02 13:48:35 +03:00
dimgigov 3881ba8271 fix(qbe): simplified if handler, unconditional @lElse/@lEnd, implicit ret fix 2026-06-02 13:45:01 +03:00
dimgigov 4c610b8a80 fix(qbe): improved if-else label handling, QBE_IsTerminator for hIf 2026-06-02 13:32:41 +03:00
dimgigov 319dcd9280 fix(qbe): QBE_EnsureLocal for all operands, uppercase hVar→0, char→w 2026-06-02 13:29:38 +03:00
dimgigov 0eadb8ab76 fix(qbe): QBE_EnsureLocal for hFieldPtr base, char types w→w 2026-06-02 13:24:08 +03:00
dimgigov 6fdbc139d0 fix(qbe): QBE_EnsureLocal — add % prefix to bare identifiers in store/call/ret 2026-06-02 13:18:15 +03:00
dimgigov a61cd198a8 fix(qbe): empty val/target fallbacks for hStore, hAssign, alloca-init 2026-06-02 13:11:40 +03:00
dimgigov cae53aeaef fix(qbe): Lcx_ResolveTypeKind — map TypeExpr.kind→Type.kind, fix alloca typeKind, skip empty stores 2026-06-02 13:02:35 +03:00
dimgigov 8d0841b6be fix(qbe): hCast passthrough, logical ops =w→=l, implicit ret, && rVal string bug 2026-06-02 12:50:51 +03:00
dimgigov 87e8b08fc8 docs: update README and LanguageRef with backtick strings + QBE backend 2026-06-02 11:36:59 +03:00
dimgigov 70cfa4f721 feat: backtick raw/multi-line strings + QBE backend fixes
- Add backtick raw string literals (Go-style ): no escape processing, multi-line
- C backend: handle backtick strings in emitExpr
- Self-hosted lexer: lexScanBacktickString support
- QBE backend: handle backtick strings in data sections
- QBE: remove broken extern declarations (QBE resolves at link time)
- QBE: fix comparison result types (ceql → w, extend to l)
- QBE: fix SSA parameter name clash (_p_ prefix for params)
- QBE: const inlining via HirLower + QBE emitter
- QBE: proper type mapping for bool/char types
- hir_lower: collect dkConst declarations for const propagation
2026-06-02 11:33:29 +03:00
dimgigov d1160ca5d1 Fix critical segfault: add bounds checking to parser diag buffer
The self-hosted compiler crashed with SIGSEGV when processing files
that generated >=256 parser diagnostics (e.g. truncated source files).
The parser allocated a fixed-size diag buffer of 256 entries, but
parserExpect, parserExpectIdentOrKeyword, and parserEmitDiag wrote
into it without checking bounds. Once diagCount exceeded 256, writes
overflowed into adjacent heap objects (Decl structs), corrupting
their kind/childDecl2 fields and causing crashes during AST traversal.

This fix adds bounds checks to all three sites so excess diagnostics
are silently dropped rather than corrupting memory. The file size
threshold (7037 vs 7062 bytes) was a red herring — it determined
how many parser errors were generated before EOF.

Closes: selfhost segfault on 250+ line files
2026-06-02 01:31:18 +03:00
dimgigov 975cc347d0 fix: selfhost CLI run command, lexer char literal, parser test path, calloc in runtime
- Fix lexer unterminated char error test (was treating 'a as lifetime)
- Fix parser test sample.bux path for root-dir execution
- Add bux_system() to runtime.c and run command to selfhost CLI
- Switch bux_alloc from malloc to calloc for zero-init
- Fix module flattening in Cli_Check/Cli_Compile to scan full decl list
- Make test passes fully, selfhost builds successfully
2026-06-02 00:50:16 +03:00
dimgigov 2b911410cb feat: self-hosting progress - Nim backend, parser fixes, 64 struct fields, 13/14 modules check 2026-06-01 23:42:25 +03:00
dimgigov 1e8e119d9e docs: remove all Rux references and comparisons
- README.md: drop 'inspired by Rux' and 'improves on Rux' language
- PLAN.md: remove Rux from comparison table, milestones, and appendix
- PLAN.md: delete entire Appendix A (Rux Language Reference)
- docs/PHASE8_STRATEGY.md: rephrase without Rux
- docs/Packages.md: drop 'Compatible with Rux.toml spec'
2026-06-01 14:09:25 +03:00
dimgigov e8d8b62c9d selfhost: fix parser infinite loop + lexer token limit
- Parser_Parse: add beforePos safeguard to skip unrecognized tokens
  instead of looping forever when parserParseDecl returns null
- Lexer: increase maxTokens 4096 -> 32768; add explicit break on limit
- CLI: null-check ReadFile result before String_Eq
- Nim CLI: add -O2 to cc invocation for faster self-hosted builds
2026-06-01 14:03:54 +03:00
dimgigov 55beb23220 WIP: Bootstrap loop debugging
- Fixed module flattening in self-hosted compiler (Cli_Compile now unwraps module wrappers)
- buxc2 check now finds functions in module-wrapped files (token.bux: funcCount=6, Main.bux: funcCount=2)
- Added debug prints to trace lexer.bux timeout and check x segfault
- Remaining issues: lexer.bux hangs in self-hosted pipeline, check x segfaults in runtime
2026-06-01 12:23:25 +03:00
dimgigov 8b2179ccf9 Phase 8.3: Fix spawn to use bux_task_spawn for non-async functions
- 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
2026-06-01 11:58:17 +03:00
dimgigov cefd2a8442 Phase 8.2.4: Slice fat pointer + bounds checking
- T[] slices are now fat pointers {data: T*, len: size_t} in C backend
- Added hSliceIndex HIR node for slice indexing (distinct from hIndexPtr for raw pointers)
- Added exprIndexBoundsCheck flag to AST ekIndex
- Sema sets bounds-check flag in @[Checked] functions
- C backend emits Slice_<T> typedefs and compound literals for slice init
- bux_bounds_check() called automatically on slice indexing in @[Checked] funcs
- Unchecked functions allow raw access (C behavior) for performance
2026-06-01 11:50:45 +03:00
dimgigov bf9e73d56e Phase 8.2.4: Lifetime syntax ('a) support
- Lexer tokenizes 'a as tkLifetime
- Parser accepts lifetimes in type params <'a> and reference types &'a T / &'a mut T
- AST TypeExpr has refLifetime field for tekRef/tekMutRef
- TypeParam gains isLifetime flag for generic monomorphization
- Sema infers lifetime params as no-op dummy values; unwraps pointee types for params inside refs
- HIR lower skips lifetime params when generating mangled names and substitution tables
- &mut expr syntax supported in parser (consumed as part of unary &)
2026-06-01 11:32:40 +03:00