(pos Pos)
| 2359 | } |
| 2360 | |
| 2361 | func (p *Parser) parseDictionaryLayoutClause(pos Pos) (*DictionaryLayoutClause, error) { |
| 2362 | if err := p.expectKeyword(KeywordLayout); err != nil { |
| 2363 | return nil, err |
| 2364 | } |
| 2365 | |
| 2366 | if err := p.expectTokenKind(TokenKindLParen); err != nil { |
| 2367 | return nil, err |
| 2368 | } |
| 2369 | |
| 2370 | layoutName, err := p.parseIdent() |
| 2371 | if err != nil { |
| 2372 | return nil, err |
| 2373 | } |
| 2374 | |
| 2375 | if err := p.expectTokenKind(TokenKindLParen); err != nil { |
| 2376 | return nil, err |
| 2377 | } |
| 2378 | |
| 2379 | var args []*DictionaryArgExpr |
| 2380 | // Parse optional arguments |
| 2381 | for !p.matchTokenKind(TokenKindRParen) { |
| 2382 | arg, err := p.parseDictionaryArgExpr(p.Pos()) |
| 2383 | if err != nil { |
| 2384 | return nil, err |
| 2385 | } |
| 2386 | args = append(args, arg) |
| 2387 | |
| 2388 | // If there's no right paren, we expect another arg (no comma needed) |
| 2389 | if p.matchTokenKind(TokenKindRParen) { |
| 2390 | break |
| 2391 | } |
| 2392 | } |
| 2393 | |
| 2394 | if err := p.expectTokenKind(TokenKindRParen); err != nil { |
| 2395 | return nil, err |
| 2396 | } |
| 2397 | |
| 2398 | rParenPos := p.Pos() |
| 2399 | if err := p.expectTokenKind(TokenKindRParen); err != nil { |
| 2400 | return nil, err |
| 2401 | } |
| 2402 | |
| 2403 | return &DictionaryLayoutClause{ |
| 2404 | LayoutPos: pos, |
| 2405 | Layout: layoutName, |
| 2406 | Args: args, |
| 2407 | RParenPos: rParenPos, |
| 2408 | }, nil |
| 2409 | } |
| 2410 | |
| 2411 | func (p *Parser) parseDictionaryRangeClause(pos Pos) (*DictionaryRangeClause, error) { |
| 2412 | if err := p.expectKeyword(KeywordRange); err != nil { |
no test coverage detected