@@ -10842,14 +10842,37 @@ parser_lex(pm_parser_t *parser) {
1084210842 following = next_newline(following, parser->end - following);
1084310843 }
1084410844
10845- // If the lex state was ignored, or we hit a '.' or a '&.',
10846- // we will lex the ignored newline
10845+ // If the lex state was ignored, we will lex the
10846+ // ignored newline.
10847+ if (lex_state_ignored_p(parser)) {
10848+ if (!lexed_comment) parser_lex_ignored_newline(parser);
10849+ lexed_comment = false;
10850+ goto lex_next_token;
10851+ }
10852+
10853+ // If we hit a '.' or a '&.' we will lex the ignored
10854+ // newline.
10855+ if (following && (
10856+ (peek_at(parser, following) == '.') ||
10857+ (peek_at(parser, following) == '&' && peek_at(parser, following + 1) == '.')
10858+ )) {
10859+ if (!lexed_comment) parser_lex_ignored_newline(parser);
10860+ lexed_comment = false;
10861+ goto lex_next_token;
10862+ }
10863+
10864+
10865+ // If we are parsing as CRuby 3.5 or later and we
10866+ // hit a '&&' or a '||' then we will lex the ignored
10867+ // newline.
1084710868 if (
10848- lex_state_ignored_p(parser) ||
10849- (following && (
10850- (peek_at(parser, following) == '.') ||
10851- (peek_at(parser, following) == '&' && peek_at(parser, following + 1) == '.')
10852- ))
10869+ (parser->version == PM_OPTIONS_VERSION_LATEST) &&
10870+ following && (
10871+ (peek_at(parser, following) == '&' && peek_at(parser, following + 1) == '&') ||
10872+ (peek_at(parser, following) == '|' && peek_at(parser, following + 1) == '|') ||
10873+ (peek_at(parser, following) == 'a' && peek_at(parser, following + 1) == 'n' && peek_at(parser, following + 2) == 'd' && !char_is_identifier(parser, following + 3, parser->end - (following + 3))) ||
10874+ (peek_at(parser, following) == 'o' && peek_at(parser, following + 1) == 'r' && !char_is_identifier(parser, following + 2, parser->end - (following + 2)))
10875+ )
1085310876 ) {
1085410877 if (!lexed_comment) parser_lex_ignored_newline(parser);
1085510878 lexed_comment = false;
@@ -10889,6 +10912,63 @@ parser_lex(pm_parser_t *parser) {
1088910912 parser->next_start = NULL;
1089010913 LEX(PM_TOKEN_AMPERSAND_DOT);
1089110914 }
10915+
10916+ if (parser->version == PM_OPTIONS_VERSION_LATEST) {
10917+ // If we hit an && then we are in a logical chain
10918+ // and we need to return the logical operator.
10919+ if (peek_at(parser, next_content) == '&' && peek_at(parser, next_content + 1) == '&') {
10920+ if (!lexed_comment) parser_lex_ignored_newline(parser);
10921+ lex_state_set(parser, PM_LEX_STATE_BEG);
10922+ parser->current.start = next_content;
10923+ parser->current.end = next_content + 2;
10924+ parser->next_start = NULL;
10925+ LEX(PM_TOKEN_AMPERSAND_AMPERSAND);
10926+ }
10927+
10928+ // If we hit a || then we are in a logical chain and
10929+ // we need to return the logical operator.
10930+ if (peek_at(parser, next_content) == '|' && peek_at(parser, next_content + 1) == '|') {
10931+ if (!lexed_comment) parser_lex_ignored_newline(parser);
10932+ lex_state_set(parser, PM_LEX_STATE_BEG);
10933+ parser->current.start = next_content;
10934+ parser->current.end = next_content + 2;
10935+ parser->next_start = NULL;
10936+ LEX(PM_TOKEN_PIPE_PIPE);
10937+ }
10938+
10939+ // If we hit an 'and' then we are in a logical chain
10940+ // and we need to return the logical operator.
10941+ if (
10942+ peek_at(parser, next_content) == 'a' &&
10943+ peek_at(parser, next_content + 1) == 'n' &&
10944+ peek_at(parser, next_content + 2) == 'd' &&
10945+ !char_is_identifier(parser, next_content + 3, parser->end - (next_content + 3))
10946+ ) {
10947+ if (!lexed_comment) parser_lex_ignored_newline(parser);
10948+ lex_state_set(parser, PM_LEX_STATE_BEG);
10949+ parser->current.start = next_content;
10950+ parser->current.end = next_content + 3;
10951+ parser->next_start = NULL;
10952+ parser->command_start = true;
10953+ LEX(PM_TOKEN_KEYWORD_AND);
10954+ }
10955+
10956+ // If we hit a 'or' then we are in a logical chain
10957+ // and we need to return the logical operator.
10958+ if (
10959+ peek_at(parser, next_content) == 'o' &&
10960+ peek_at(parser, next_content + 1) == 'r' &&
10961+ !char_is_identifier(parser, next_content + 2, parser->end - (next_content + 2))
10962+ ) {
10963+ if (!lexed_comment) parser_lex_ignored_newline(parser);
10964+ lex_state_set(parser, PM_LEX_STATE_BEG);
10965+ parser->current.start = next_content;
10966+ parser->current.end = next_content + 2;
10967+ parser->next_start = NULL;
10968+ parser->command_start = true;
10969+ LEX(PM_TOKEN_KEYWORD_OR);
10970+ }
10971+ }
1089210972 }
1089310973
1089410974 // At this point we know this is a regular newline, and we can set the
0 commit comments