| ... | ... | @@ -272,6 +272,7 @@ pub const Tokenizer = struct { |
| 272 | 272 | U, |
| 273 | 273 | L, |
| 274 | 274 | StringLiteral, |
| 275 | AfterStringLiteral, |
| 275 | 276 | CharLiteralStart, |
| 276 | 277 | CharLiteral, |
| 277 | 278 | EscapeSequence, |
| ... | ... | @@ -565,8 +566,7 @@ pub const Tokenizer = struct { |
| 565 | 566 | state = .EscapeSequence; |
| 566 | 567 | }, |
| 567 | 568 | '"' => { |
| 568 | | self.index += 1; |
| 569 | | break; |
| 569 | state = .AfterStringLiteral; |
| 570 | 570 | }, |
| 571 | 571 | '\n', '\r' => { |
| 572 | 572 | result.id = .Invalid; |
| ... | ... | @@ -574,6 +574,15 @@ pub const Tokenizer = struct { |
| 574 | 574 | }, |
| 575 | 575 | else => {}, |
| 576 | 576 | }, |
| 577 | .AfterStringLiteral => switch (c) { |
| 578 | '"' => { |
| 579 | state = .StringLiteral; |
| 580 | }, |
| 581 | '\n'...'\r', ' ' => {}, |
| 582 | else => { |
| 583 | break; |
| 584 | }, |
| 585 | }, |
| 577 | 586 | .CharLiteralStart => switch (c) { |
| 578 | 587 | '\\' => { |
| 579 | 588 | string = false; |
| ... | ... | @@ -1109,6 +1118,7 @@ pub const Tokenizer = struct { |
| 1109 | 1118 | } |
| 1110 | 1119 | } else if (self.index == self.source.buffer.len) { |
| 1111 | 1120 | switch (state) { |
| 1121 | .AfterStringLiteral, |
| 1112 | 1122 | .Start => {}, |
| 1113 | 1123 | .u, .u8, .U, .L, .Identifier => { |
| 1114 | 1124 | result.id = Token.getKeyword(self.source.buffer[result.start..self.index], self.prev_tok_id == .Hash and !self.pp_directive) orelse .Identifier; |
| ... | ... | @@ -1351,11 +1361,11 @@ test "line continuation" { |
| 1351 | 1361 | |
| 1352 | 1362 | test "string prefix" { |
| 1353 | 1363 | expectTokens( |
| 1354 | | \\"foo" |
| 1355 | | \\u"foo" |
| 1356 | | \\u8"foo" |
| 1357 | | \\U"foo" |
| 1358 | | \\L"foo" |
| 1364 | \\"foo" "bar" |
| 1365 | \\u"foo" "bar" |
| 1366 | \\u8"foo" "bar" |
| 1367 | \\U"foo" "bar" |
| 1368 | \\L"foo" "bar" |
| 1359 | 1369 | \\'foo' |
| 1360 | 1370 | \\u'foo' |
| 1361 | 1371 | \\U'foo' |