Skip to content

Comments

Implement Phase 2: Contracts, Ownership, Spawn, Assert, and Test Blocks#7

Merged
benpayne merged 3 commits intomasterfrom
claude/phase-2-planning-KkQhj
Feb 24, 2026
Merged

Implement Phase 2: Contracts, Ownership, Spawn, Assert, and Test Blocks#7
benpayne merged 3 commits intomasterfrom
claude/phase-2-planning-KkQhj

Conversation

@benpayne
Copy link
Owner

Summary

This PR implements Phase 2 of the BLang compiler, adding support for function contracts (requires/ensures), ownership qualifiers (own/shared/sync), spawn statements, assert statements, test blocks, and async/await stubs. It includes a complete runtime library for reference counting and thread pool management.

Key Changes

Language Features

  • Function Contracts: Added requires (preconditions) and ensures (postconditions) clauses with compile-time parsing and runtime checking
  • Ownership Qualifiers: Implemented own, shared, and sync qualifiers for variables with distinct memory management strategies
  • Spawn Statements: Added spawn { } blocks for concurrent task submission (currently sequential stubs)
  • Assert Statements: Implemented assert expr; and assert expr, "message"; with optional failure messages
  • Test Blocks: Added test "name" { } syntax for unit tests with automatic test runner generation
  • Async/Await: Added async fn declarations and await expr expressions (synchronous stubs for now)
  • For-In Loops: Implemented range-based iteration with for i in 0..N syntax
  • Event Handlers: Added on expr { } event handler syntax

Code Generation

  • Contract Checking: Generates runtime checks for requires clauses at function entry and ensures clauses before all return paths
  • Reference Counting: Shared/sync variables allocate on heap via __blang_rc_alloc and __blang_rc_alloc_sync, with automatic retain/release
  • Synchronization: Sync variables use mutex locks around load/store operations
  • Test Runner: Automatically generates a test runner function that calls all test blocks
  • Result Variable: For functions with ensures clauses, creates implicit result variable accessible in postconditions

Runtime Library

  • ARC Implementation (blang_runtime.c): Reference counting with atomic operations, mutex support for sync objects
  • Thread Pool: Green thread pool with configurable worker threads for spawn task execution
  • Channel Support: Basic channel implementation with send/receive operations
  • Helper Functions: Declarations for puts, printf, exit, and BLang-specific runtime functions

Parser & Lexer

  • Added 15+ new keywords: own, shared, sync, spawn, assert, test, requires, ensures, async, await, on, chan, in, break, continue
  • Extended statement parsing to handle spawn, assert, event handlers, and test blocks
  • Extended expression parsing for await expressions
  • Updated variable declaration parsing to recognize ownership qualifiers

Testing

  • Added 30+ new test files covering all Phase 2 features
  • Tests for ownership qualifiers, contracts, spawn, assert, async/await, for-in loops
  • Both positive (pass/) and negative (fail/) test cases
  • Comprehensive end-to-end codegen tests

Notable Implementation Details

  • Ownership Strategy: own uses stack allocation with move semantics (stub), shared and sync use heap allocation with ARC
  • Contract Evaluation: Ensures clauses can reference implicit result variable for return value validation
  • Spawn Execution: Currently executes spawn blocks sequentially; runtime library supports async execution via thread pool
  • Test Generation: Module-level test blocks are collected and wrapped in callable functions with automatic test runner
  • Memory Layout: Shared/sync objects prepend a BlangRefHeader containing ref count, sync flag, and mutex pointer

https://claude.ai/code/session_01JWnUURggw1VQCApVkghxLV

…ts, testing

Add parser support for all five Phase 2 sub-phases:

- 2.1 Ownership: own/shared/sync qualifiers on variable declarations with
  OwnershipQualifier enum and move tracking on VariableDefinition
- 2.2 Concurrency: spawn { } blocks parsed into SpawnStatement AST nodes;
  chan keyword added to lexer for future channel type support
- 2.3 Async/Await: async fn declarations with mIsAsync flag, await prefix
  expressions as AwaitExpression nodes, on expr { } event handlers
- 2.4 Contracts: requires/ensures clauses parsed after function return types,
  stored as clause text on FunctionDefinition
- 2.5 Testing: test "name" { } blocks parsed into TestBlock at module level,
  assert expr; statements with optional failure messages

12 new lexer keywords, 5 new AST node classes, 4 new parser source files,
25 new test files (19 pass + 6 fail). All 108 tests pass (81 pass + 27 fail).
Existing test functions named 'test' renamed to 'run_test' since test is
now a reserved keyword.

https://claude.ai/code/session_01JWnUURggw1VQCApVkghxLV
…, test blocks

Add LLVM IR generation for all Phase 2 language features:
- Assert statements with optional messages (conditional branch to exit(1))
- Contract clauses (requires/ensures) as runtime checks with expression ASTs
- Spawn blocks (sequential stub - inline body execution)
- Async/await (synchronous stubs - direct evaluation)
- Event handlers (sequential stub - inline body execution)
- Test blocks (__blang_test_* functions + __blang_run_tests runner)

Fix critical lexer enum collision: Phase 2 keyword enum values (e.g.
KEYWORD_ENSURES=45) collided with ASCII operator characters ('-'=45),
causing the expression parser to misparse contract clauses. Fixed by
starting Phase 2 keywords at enum value 256.

Change contract clause storage from strings to Expression ASTs in Type.h,
enabling proper codegen evaluation of requires/ensures conditions.

All 108 parse tests pass, all E2E codegen tests pass (assert, contracts,
spawn, async, phase2 comprehensive + existing Phase 1 tests).

https://claude.ai/code/session_01JWnUURggw1VQCApVkghxLV
Create runtime library (runtime/blang_runtime.{h,c}) providing:
- ARC (automatic reference counting): alloc, retain, release for
  shared/sync heap-allocated variables
- Thread pool: init, spawn, shutdown for green thread execution
- Channels: create, send, recv, close, destroy for inter-thread comms
- Async tasks: async_call, await, task_destroy for async/await support
All backed by pthreads with proper synchronization.

Update CodeGen for ownership qualifiers:
- shared variables: heap-allocated via __blang_rc_alloc, loads/stores
  go through the heap pointer indirection
- sync variables: heap-allocated via __blang_rc_alloc_sync, assignments
  wrapped in __blang_sync_lock/__blang_sync_unlock calls
- own variables: stack-allocated with move semantics tracking

Add for-in range loop codegen: for x in start..end generates proper
loop with counter variable, condition check, and increment.

Update build system: CMakeLists.txt builds libblang_runtime.a static
library and PIC object file for linking into BLang programs.

Update test_codegen.sh: links runtime library when available, uses
set +e for binary execution to handle non-zero exit codes gracefully.

New E2E tests: codegen_ownership.b, codegen_forin.b,
codegen_comprehensive.b exercising all Phase 2 features together.

All 108 parse tests pass, all 11 E2E codegen tests pass.

https://claude.ai/code/session_01JWnUURggw1VQCApVkghxLV
@benpayne benpayne merged commit bb2e39c into master Feb 24, 2026
5 checks passed
@benpayne benpayne deleted the claude/phase-2-planning-KkQhj branch February 24, 2026 01:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants