* parses for x in expr for y in expr if expr for z in expr ... */
(forToken *token, end tokenKind)
| 676 | |
| 677 | /* parses for x in expr for y in expr if expr for z in expr ... */ |
| 678 | func (p *parser) parseComprehensionSpecs(forToken *token, end tokenKind) (*ast.ForSpec, *token, errors.StaticError) { |
| 679 | var parseComprehensionSpecsHelper func(forToken *token, outer *ast.ForSpec) (*ast.ForSpec, *token, errors.StaticError) |
| 680 | parseComprehensionSpecsHelper = func(forToken *token, outer *ast.ForSpec) (*ast.ForSpec, *token, errors.StaticError) { |
| 681 | var ifSpecs []ast.IfSpec |
| 682 | |
| 683 | varID, popErr := p.popExpect(tokenIdentifier) |
| 684 | if popErr != nil { |
| 685 | return nil, nil, popErr |
| 686 | } |
| 687 | id := ast.Identifier(varID.data) |
| 688 | inToken, err := p.popExpect(tokenIn) |
| 689 | if err != nil { |
| 690 | return nil, nil, err |
| 691 | } |
| 692 | arr, err := p.parse(iast.MaxPrecedence) |
| 693 | if err != nil { |
| 694 | return nil, nil, err |
| 695 | } |
| 696 | forSpec := &ast.ForSpec{ |
| 697 | ForFodder: forToken.fodder, |
| 698 | VarFodder: varID.fodder, |
| 699 | VarName: id, |
| 700 | InFodder: inToken.fodder, |
| 701 | Expr: arr, |
| 702 | Outer: outer, |
| 703 | } |
| 704 | |
| 705 | maybeIf := p.pop() |
| 706 | for ; maybeIf.kind == tokenIf; maybeIf = p.pop() { |
| 707 | cond, err := p.parse(iast.MaxPrecedence) |
| 708 | if err != nil { |
| 709 | return nil, nil, err |
| 710 | } |
| 711 | ifSpecs = append(ifSpecs, ast.IfSpec{ |
| 712 | IfFodder: maybeIf.fodder, |
| 713 | Expr: cond, |
| 714 | }) |
| 715 | } |
| 716 | forSpec.Conditions = ifSpecs |
| 717 | if maybeIf.kind == end { |
| 718 | return forSpec, maybeIf, nil |
| 719 | } |
| 720 | |
| 721 | if maybeIf.kind != tokenFor { |
| 722 | return nil, nil, errors.MakeStaticError( |
| 723 | fmt.Sprintf("Expected for, if or %v after for clause, got: %v", end, maybeIf), maybeIf.loc) |
| 724 | } |
| 725 | |
| 726 | return parseComprehensionSpecsHelper(maybeIf, forSpec) |
| 727 | } |
| 728 | return parseComprehensionSpecsHelper(forToken, nil) |
| 729 | } |
| 730 | |
| 731 | // Assumes that the leading '[' has already been consumed and passed as tok. |
| 732 | // Should read up to and consume the trailing ']' |
no test coverage detected