Temporary chapter name for all chapters
parens

Parentheses. 2*(3+4) should be 14. Whatever sits inside (...) evaluates to one number, and the outer expression treats that number like any other operand.

To support this we split eval into two helpers:

- parseExpression(source, pos) -- the loop you already have, but reads operands by calling numberOrParens and stops on ) or 0.
- numberOrParens(source, pos) -- reads one operand: a number, or (, recurse into parseExpression, then expect ).

eval becomes a thin wrapper that sets up state and calls parseExpression.

    testCase("(2+3)", 5);
    testCase("2*(3+4)", 14);   // without parens: 2*3+4 = 10
    testCase("8-(3+4)", 1);    // without parens: 8-3+4 = 9
    testCase("((1+2)*(3+4))", 21);
fn numberOrParens(source: [*]const u8, pos: *usize) i64 {
    if (source[pos.*] == '(') {
        pos.* += 1;
        skipSpaces(source, pos);
        const val: i64 = parseExpression(source, pos);
        if (source[pos.*] == ')') {
            pos.* += 1;
            skipSpaces(source, pos);
        }
        return val;
    }
    return readNumber(source, pos);
}

fn parseExpression(source: [*]const u8, pos: *usize) i64 {
    var val: i64 = numberOrParens(source, pos);
    while (source[pos.*] != 0 and source[pos.*] != ')') {
        const op: u8 = source[pos.*];
        pos.* += 1;
        skipSpaces(source, pos);
        const right: i64 = numberOrParens(source, pos);
        val = switch (op) {
            '+' => val + right,
            '-' => val - right,
            '*' => val * right,
            '/' => @divTrunc(val, right),
            else => val,
        };
    }
    return val;
}

fn eval(input: []const u8) i64 {
    const source: [*]const u8 = input.ptr;
    var pos: usize = 0;
    skipSpaces(source, &pos);
    return parseExpression(source, &pos);
}

Notice something: inside the helpers we write parseExpression(source, pos) -- no &, because pos is already a *usize pointer here. We only use &pos inside eval, where pos is a local usize variable and we need to take its address to hand it out.

Also notice: 2+3*4 still gives 20 here -- parens don't fix precedence on their own. But you can write 2+(3*4) to get 14. The escape hatch.