windjammer 0.48.0

A simple language inspired by Go, Ruby, and Elixir that transpiles to Rust - 80% of Rust's power with 20% of the complexity
Documentation
// Conformance Test: Mutation Semantics
//
// SEMANTIC CONTRACT:
// - `let` bindings are immutable by default
// - `let mut` bindings can be reassigned
// - Functions that mutate parameters change the caller's value
// - Functions that only read parameters leave the caller's value unchanged
// - Compound assignment operators (+=, -=, *=) work correctly
//
// EXPECTED OUTPUT:
// [mut_basic] before: x=10
// [mut_basic] after: x=20
// [mut_compound] x=10
// [mut_compound] after +=5: x=15
// [mut_compound] after -=3: x=12
// [mut_compound] after *=2: x=24
// [mut_fn_read] items before: len=3
// [mut_fn_read] total=6
// [mut_fn_read] items after: len=3
// [mut_fn_push] items before: len=2
// [mut_fn_push] items after: len=3
// [mut_fn_push] last item: 30
// [mut_struct] before: hp=100
// [mut_struct] after damage: hp=70
// [mut_struct] after heal: hp=90
// [mut_all] PASSED

// --- Test: Basic mutability ---
fn test_mut_basic() {
    let mut x = 10
    println("[mut_basic] before: x=${x}")
    x = 20
    println("[mut_basic] after: x=${x}")
}

// --- Test: Compound assignment operators ---
fn test_mut_compound() {
    let mut x = 10
    println("[mut_compound] x=${x}")
    x += 5
    println("[mut_compound] after +=5: x=${x}")
    x -= 3
    println("[mut_compound] after -=3: x=${x}")
    x *= 2
    println("[mut_compound] after *=2: x=${x}")
}

// --- Test: Function reads parameter without mutating ---
fn sum_items(items: Vec<int>) -> int {
    let mut total = 0
    for item in items {
        total += item
    }
    total
}

fn test_fn_read() {
    let items = vec![1, 2, 3]
    println("[mut_fn_read] items before: len=${items.len()}")
    let total = sum_items(items)
    println("[mut_fn_read] total=${total}")
    println("[mut_fn_read] items after: len=${items.len()}")
}

// --- Test: Function mutates parameter ---
fn add_item(items: Vec<int>, item: int) {
    items.push(item)
}

fn test_fn_push() {
    let mut items = vec![10, 20]
    println("[mut_fn_push] items before: len=${items.len()}")
    add_item(items, 30)
    println("[mut_fn_push] items after: len=${items.len()}")
    println("[mut_fn_push] last item: ${items[2]}")
}

// --- Test: Struct field mutation through methods ---
struct Player {
    hp: int,
}

impl Player {
    fn new(hp: int) -> Player {
        Player { hp }
    }

    fn damage(self, amount: int) {
        self.hp -= amount
    }

    fn heal(self, amount: int) {
        self.hp += amount
    }
}

fn test_struct_mutation() {
    let mut player = Player::new(100)
    println("[mut_struct] before: hp=${player.hp}")
    player.damage(30)
    println("[mut_struct] after damage: hp=${player.hp}")
    player.heal(20)
    println("[mut_struct] after heal: hp=${player.hp}")
}

fn main() {
    test_mut_basic()
    test_mut_compound()
    test_fn_read()
    test_fn_push()
    test_struct_mutation()
    println("[mut_all] PASSED")
}