code: func (p *Parser) parseCall(name string) (*Call, error) {
  	name = strings.ToLower(name)
  
  	// Parse first function argument if one exists.
  	var args []Expr
  	re, err := p.parseRegex()
  	if err != nil {
  		return nil, err
  	} else if re != nil {
  		args = append(args, re)
  	} else {
  		// If there's a right paren then just return immediately.
  		if tok, _, _ := p.Scan(); tok == RPAREN {
  			return &Call{Name: name}, nil
  		}
  		p.Unscan()
  
  		arg, err := p.ParseExpr()
  		if err != nil {
  			return nil, err
  		}
  		args = append(args, arg)
  	}
  
  	// Parse additional function arguments if there is a comma.
  	for {
  		// If there's not a comma, stop parsing arguments.
  		if tok, _, _ := p.ScanIgnoreWhitespace(); tok != COMMA {
  			p.Unscan()
  			break
  		}
  
  		re, err := p.parseRegex()
  		if err != nil {
  			return nil, err
  		} else if re != nil {
  			args = append(args, re)
  			continue
  		}
  
  		// Parse an expression argument.
  		arg, err := p.ParseExpr()
  		if err != nil {
  			return nil, err
  		}
  		args = append(args, arg)
  	}
  
  	// There should be a right parentheses at the end.
  	if tok, pos, lit := p.Scan(); tok != RPAREN {
  		return nil, newParseError(tokstr(tok, lit), []string{")"}, pos)
  	}
  
  	return &Call{Name: name, Args: args}, nil
  }
docs: // parseCall parses a function call.
  // This function assumes the function name and LPAREN have been consumed.