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
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 | + | } |