| ... | @@ -220,6 +220,8 @@ pub const Tokenizer = struct { | ... | @@ -220,6 +220,8 @@ pub const Tokenizer = struct { |
| 220 | MultilineStringLiteralLineBackslash, | 220 | MultilineStringLiteralLineBackslash, |
| 221 | CharLiteral, | 221 | CharLiteral, |
| 222 | CharLiteralBackslash, | 222 | CharLiteralBackslash, |
| | 223 | CharLiteralEscape1, |
| | 224 | CharLiteralEscape2, |
| 223 | CharLiteralEnd, | 225 | CharLiteralEnd, |
| 224 | Backslash, | 226 | Backslash, |
| 225 | Equal, | 227 | Equal, |
| ... | @@ -612,9 +614,32 @@ pub const Tokenizer = struct { | ... | @@ -612,9 +614,32 @@ pub const Tokenizer = struct { |
| 612 | result.id = Token.Id.Invalid; | 614 | result.id = Token.Id.Invalid; |
| 613 | break; | 615 | break; |
| 614 | }, | 616 | }, |
| | 617 | 'x' => { |
| | 618 | state = State.CharLiteralEscape1; |
| | 619 | }, |
| | 620 | else => { |
| | 621 | state = State.CharLiteralEnd; |
| | 622 | }, |
| | 623 | }, |
| | 624 | |
| | 625 | State.CharLiteralEscape1 => switch (c) { |
| | 626 | '0'...'9', 'a'...'z', 'A'...'F' => { |
| | 627 | state = State.CharLiteralEscape2; |
| | 628 | }, |
| 615 | else => { | 629 | else => { |
| | 630 | result.id = Token.Id.Invalid; |
| | 631 | break; |
| | 632 | }, |
| | 633 | }, |
| | 634 | |
| | 635 | State.CharLiteralEscape2 => switch (c) { |
| | 636 | '0'...'9', 'a'...'z', 'A'...'F' => { |
| 616 | state = State.CharLiteralEnd; | 637 | state = State.CharLiteralEnd; |
| 617 | }, | 638 | }, |
| | 639 | else => { |
| | 640 | result.id = Token.Id.Invalid; |
| | 641 | break; |
| | 642 | }, |
| 618 | }, | 643 | }, |
| 619 | | 644 | |
| 620 | State.CharLiteralEnd => switch (c) { | 645 | State.CharLiteralEnd => switch (c) { |
| ... | @@ -988,6 +1013,8 @@ pub const Tokenizer = struct { | ... | @@ -988,6 +1013,8 @@ pub const Tokenizer = struct { |
| 988 | State.MultilineStringLiteralLineBackslash, | 1013 | State.MultilineStringLiteralLineBackslash, |
| 989 | State.CharLiteral, | 1014 | State.CharLiteral, |
| 990 | State.CharLiteralBackslash, | 1015 | State.CharLiteralBackslash, |
| | 1016 | State.CharLiteralEscape1, |
| | 1017 | State.CharLiteralEscape2, |
| 991 | State.CharLiteralEnd, | 1018 | State.CharLiteralEnd, |
| 992 | State.StringLiteralBackslash => { | 1019 | State.StringLiteralBackslash => { |
| 993 | result.id = Token.Id.Invalid; | 1020 | result.id = Token.Id.Invalid; |
| ... | @@ -1127,6 +1154,13 @@ test "tokenizer" { | ... | @@ -1127,6 +1154,13 @@ test "tokenizer" { |
| 1127 | }); | 1154 | }); |
| 1128 | } | 1155 | } |
| 1129 | | 1156 | |
| | 1157 | test "tokenizer - char literal with hex escape" { |
| | 1158 | testTokenize( \\'\x1b' |
| | 1159 | , []Token.Id { |
| | 1160 | Token.Id.CharLiteral, |
| | 1161 | }); |
| | 1162 | } |
| | 1163 | |
| 1130 | test "tokenizer - float literal e exponent" { | 1164 | test "tokenizer - float literal e exponent" { |
| 1131 | testTokenize("a = 4.94065645841246544177e-324;\n", []Token.Id { | 1165 | testTokenize("a = 4.94065645841246544177e-324;\n", []Token.Id { |
| 1132 | Token.Id.Identifier, | 1166 | Token.Id.Identifier, |