diff options
| -rw-r--r-- | prism/prism.c | 41 | ||||
| -rw-r--r-- | test/prism/snapshots/dos_endings.txt | 2 | ||||
| -rw-r--r-- | test/prism/snapshots/spanning_heredoc.txt | 2 | ||||
| -rw-r--r-- | test/prism/snapshots/whitequark/parser_slash_slash_n_escaping_in_literals.txt | 2 | ||||
| -rw-r--r-- | test/prism/unescape_test.rb | 6 |
5 files changed, 36 insertions, 17 deletions
diff --git a/prism/prism.c b/prism/prism.c index 36d83db191..77a813138b 100644 --- a/prism/prism.c +++ b/prism/prism.c @@ -6387,6 +6387,13 @@ escape_read(pm_parser_t *parser, pm_buffer_t *buffer, uint8_t flags) { pm_buffer_append_u8(buffer, escape_byte(peeked, flags | PM_ESCAPE_FLAG_META)); return; } + case '\r': { + if (peek_offset(parser, 1) == '\n') { + parser->current.end += 2; + pm_buffer_append_u8(buffer, '\n'); + return; + } + } default: { if (parser->current.end < parser->end) { pm_buffer_append_u8(buffer, *parser->current.end++); @@ -7918,10 +7925,11 @@ parser_lex(pm_parser_t *parser) { parser->current.end++; break; case '\r': - pm_buffer_append_u8(&buffer, '\r'); parser->current.end++; - - if (peek(parser) != '\n') break; + if (peek(parser) != '\n') { + pm_buffer_append_u8(&buffer, '\r'); + break; + } /* fallthrough */ case '\n': pm_buffer_append_u8(&buffer, '\n'); @@ -13438,25 +13446,34 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power) { // the first string content we've seen. In that case we're going // to create a new string node and set that to the current. parser_lex(parser); - current = (pm_node_t *) pm_symbol_node_create_and_unescape(parser, &opening, &parser->previous, &closing, PM_UNESCAPE_ALL); + + pm_symbol_node_t *symbol = pm_symbol_node_create(parser, &opening, &parser->previous, &closing); + symbol->unescaped = parser->current_string; + + current = (pm_node_t *) symbol; } else if (PM_NODE_TYPE_P(current, PM_INTERPOLATED_SYMBOL_NODE)) { // If we hit string content and the current node is an // interpolated string, then we need to append the string content // to the list of child nodes. - pm_node_t *part = parse_string_part(parser); - pm_interpolated_symbol_node_append((pm_interpolated_symbol_node_t *) current, part); + parser_lex(parser); + + pm_string_node_t *string = pm_string_node_create(parser, &opening, &parser->previous, &closing); + string->unescaped = parser->current_string; + + pm_interpolated_symbol_node_append((pm_interpolated_symbol_node_t *) current, (pm_node_t *) string); } else if (PM_NODE_TYPE_P(current, PM_SYMBOL_NODE)) { // If we hit string content and the current node is a string node, // then we need to convert the current node into an interpolated // string and add the string content to the list of child nodes. - pm_token_t opening = not_provided(parser); - pm_token_t closing = not_provided(parser); - pm_interpolated_symbol_node_t *interpolated = - pm_interpolated_symbol_node_create(parser, &opening, NULL, &closing); + parser_lex(parser); + + pm_interpolated_symbol_node_t *interpolated = pm_interpolated_symbol_node_create(parser, &opening, NULL, &closing); pm_interpolated_symbol_node_append(interpolated, current); - pm_node_t *part = parse_string_part(parser); - pm_interpolated_symbol_node_append(interpolated, part); + pm_string_node_t *string = pm_string_node_create(parser, &opening, &parser->previous, &closing); + string->unescaped = parser->current_string; + + pm_interpolated_symbol_node_append(interpolated, (pm_node_t *) string); current = (pm_node_t *) interpolated; } else { assert(false && "unreachable"); diff --git a/test/prism/snapshots/dos_endings.txt b/test/prism/snapshots/dos_endings.txt index 73390ffad1..d01c5a7ac9 100644 --- a/test/prism/snapshots/dos_endings.txt +++ b/test/prism/snapshots/dos_endings.txt @@ -36,7 +36,7 @@ │ │ ├── opening_loc: ∅ │ │ ├── value_loc: (4,3)-(5,1) = "a\\\r\nb" │ │ ├── closing_loc: ∅ - │ │ └── unescaped: "ab" + │ │ └── unescaped: "a\nb" │ ├── opening_loc: (4,0)-(4,3) = "%I{" │ └── closing_loc: (5,1)-(5,2) = "}" ├── @ StringNode (location: (7,0)-(7,4)) diff --git a/test/prism/snapshots/spanning_heredoc.txt b/test/prism/snapshots/spanning_heredoc.txt index cb99a343ab..884028f054 100644 --- a/test/prism/snapshots/spanning_heredoc.txt +++ b/test/prism/snapshots/spanning_heredoc.txt @@ -285,7 +285,7 @@ │ │ │ │ ├── opening_loc: ∅ │ │ │ │ ├── value_loc: (48,12)-(48,14) = "p\\" │ │ │ │ ├── closing_loc: ∅ - │ │ │ │ └── unescaped: "p\\" + │ │ │ │ └── unescaped: "p" │ │ │ └── @ StringNode (location: (51,0)-(51,1)) │ │ │ ├── flags: ∅ │ │ │ ├── opening_loc: ∅ diff --git a/test/prism/snapshots/whitequark/parser_slash_slash_n_escaping_in_literals.txt b/test/prism/snapshots/whitequark/parser_slash_slash_n_escaping_in_literals.txt index 2de7dd439c..20496c3cfc 100644 --- a/test/prism/snapshots/whitequark/parser_slash_slash_n_escaping_in_literals.txt +++ b/test/prism/snapshots/whitequark/parser_slash_slash_n_escaping_in_literals.txt @@ -15,7 +15,7 @@ │ │ ├── opening_loc: ∅ │ │ ├── value_loc: (4,3)-(5,1) = "a\\\nb" │ │ ├── closing_loc: ∅ - │ │ └── unescaped: "ab" + │ │ └── unescaped: "a\nb" │ ├── opening_loc: (4,0)-(4,3) = "%I{" │ └── closing_loc: (5,1)-(5,2) = "}" ├── @ StringNode (location: (7,0)-(8,2)) diff --git a/test/prism/unescape_test.rb b/test/prism/unescape_test.rb index 4104b051dd..0053fdd364 100644 --- a/test/prism/unescape_test.rb +++ b/test/prism/unescape_test.rb @@ -75,6 +75,7 @@ module Prism ascii = (0...128).map(&:chr) ascii8 = (128...256).map(&:chr) + newlines = ["\r\n"] octal = [*("0".."7")] octal = octal.product(octal).map(&:join).concat(octal.product(octal).product(octal).map(&:join)) @@ -90,7 +91,8 @@ module Prism ctrls = (ascii.grep(/[[:print:]]/) - ["\\"]).flat_map { |c| ["C-#{c}", "c#{c}", "M-#{c}", "M-\\C-#{c}", "M-\\c#{c}", "c\\M-#{c}"] } - escapes = [*ascii, *ascii8, *octal, *hex2, *hex4, *hex6, *ctrls] + escapes = [*ascii, *ascii8, *newlines, *octal, *hex2, *hex4, *hex6, *ctrls] + contexts = [ [Context::String.new("?", ""), escapes], # [Context::String.new("'", "'"), escapes], @@ -106,7 +108,7 @@ module Prism [Context::List.new("%w[", "]"), escapes], [Context::List.new("%W[", "]"), escapes], [Context::List.new("%i[", "]"), escapes], - # [Context::List.new("%I[", "]"), escapes], + [Context::List.new("%I[", "]"), escapes], # [Context::Symbol.new("%s[", "]"), escapes], # [Context::Symbol.new(":'", "'"), escapes], # [Context::Symbol.new(":\"", "\""), escapes], |
