lang: Parse array elements in normal context

8bbc22f37c716cccdc90b8b5a73e3526ac60703c5b69ec67dc4202c2c1de7892
Array elements inherited the enclosing condition context, where
an opening brace terminates the condition. Record literals inside
bracketed arrays were consequently rejected as condition bodies.

Parse the contents of an array literal in normal expression context
and restore the enclosing context after its closing bracket.

Assisted-by: Codex:gpt-5.6-sol
Alexis Sellier committed ago 1 parent 0268ebd6
lib/std/lang/parser.rad +5 -0
241 241
/// Parse an array literal: `[a, b, c]` or `[item; count]`.
242 242
fn parseArrayLiteral(p: *mut Parser) -> *ast::Node
243 243
    throws (ParseError)
244 244
{
245 245
    try expect(p, scanner::TokenKind::LBracket, "expected `[`");
246 +
    let saved = p.context;
247 +
    set p.context = Context::Normal;
246 248
    if consume(p, scanner::TokenKind::RBracket) { // Empty array: `[]`.
247 249
        let empty: *mut [*ast::Node] = &mut [];
250 +
        set p.context = saved;
248 251
        return node(p, ast::NodeValue::ArrayLit(empty));
249 252
    }
250 253
    let firstExpr = try parseExpr(p);
251 254
252 255
    if consume(p, scanner::TokenKind::Semicolon) {
253 256
        // Array repeat literal: `[item; count]`.
254 257
        let count = try parseExpr(p);
255 258
        try expect(p, scanner::TokenKind::RBracket, "expected `]` after array repeat count");
259 +
        set p.context = saved;
256 260
257 261
        return node(p, ast::NodeValue::ArrayRepeatLit(
258 262
            ast::ArrayRepeatLit { item: firstExpr, count }
259 263
        ));
260 264
    }
264 268
    while consume(p, scanner::TokenKind::Comma) and not check(p, scanner::TokenKind::RBracket) {
265 269
        let elem = try parseExpr(p);
266 270
        items.append(elem, p.allocator);
267 271
    }
268 272
    try expect(p, scanner::TokenKind::RBracket, "expected `]` after array elements");
273 +
    set p.context = saved;
269 274
270 275
    return node(p, ast::NodeValue::ArrayLit(items));
271 276
}
272 277
273 278
/// Parse a function call expression.
test/tests/parser.condition.array.record.rad added +11 -0
1 +
//! returns: 0
2 +
//! Bracketed array elements may contain record literals in a condition.
3 +
4 +
record Box { value: i32 }
5 +
6 +
@default fn main() -> i32 {
7 +
    if [Box { value: 1 }][0].value == 1 {
8 +
        return 0;
9 +
    }
10 +
    return 1;
11 +
}