lang: Parse array elements in normal context
4e1403a045b01e77241b94d501d6e312246acae9d4a84225b42c757bbf6ea5c1
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
3c89648c
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 | + | } |