lang: Parse subscripts in normal context

a6544dc6a7a5fde7fcdfe40dc45e05e59e26fc7672cbfade85e9c045b06a873b
Subscript and slice bounds inherited the enclosing condition
context. A record literal used to compute a bracketed index was
mistaken for the condition body and rejected.

Parse expressions between subscript brackets in normal expression
context and restore the enclosing context afterward.

Assisted-by: Codex:gpt-5.6-sol
Alexis Sellier committed ago 1 parent 8bbc22f3
lib/std/lang/parser.rad +3 -0
339 339
/// Parse array subscript or slice expression after `[`.
340 340
fn parseSubscriptOrSlice(p: *mut Parser, container: *ast::Node) -> *ast::Node
341 341
    throws (ParseError)
342 342
{
343 343
    try expect(p, scanner::TokenKind::LBracket, "expected `[`");
344 +
    let saved = p.context;
345 +
    set p.context = Context::Normal;
344 346
345 347
    let mut index: *ast::Node = undefined;
346 348
347 349
    if consume(p, scanner::TokenKind::DotDot) {
348 350
        // Either `..` or `..end`.
370 372
            // Just `n` - regular indexing.
371 373
            set index = startExpr;
372 374
        }
373 375
    }
374 376
    try expect(p, scanner::TokenKind::RBracket, "expected `]` after array index");
377 +
    set p.context = saved;
375 378
376 379
    return node(p, ast::NodeValue::Subscript { container, index });
377 380
}
378 381
379 382
/// Parse postfix operators (eg. field access, function call etc.)
test/tests/parser.condition.subscript.record.rad added +12 -0
1 +
//! returns: 0
2 +
//! Bracketed subscript expressions may contain record literals in a condition.
3 +
4 +
record Index { value: u32 }
5 +
6 +
@default fn main() -> i32 {
7 +
    let values: [i32; 1] = [7];
8 +
    if values[Index { value: 0 }.value] == 7 {
9 +
        return 0;
10 +
    }
11 +
    return 1;
12 +
}