| ... | ... | @@ -7,21 +7,15 @@ pub const Source = struct { |
| 7 | 7 | }; |
| 8 | 8 | |
| 9 | 9 | pub const Token = struct { |
| 10 | | id: Id, |
| 11 | | num_suffix: NumSuffix = .None, |
| 12 | | start: usize, |
| 13 | | end: usize, |
| 14 | | source: *Source, |
| 15 | | |
| 16 | | pub const Id = enum { |
| 10 | id: union(enum) { |
| 17 | 11 | Invalid, |
| 18 | 12 | Eof, |
| 19 | 13 | Nl, |
| 20 | 14 | Identifier, |
| 21 | | StringLiteral, |
| 22 | | CharLiteral, |
| 23 | | IntegerLiteral, |
| 24 | | FloatLiteral, |
| 15 | StringLiteral: StrKind, |
| 16 | CharLiteral: StrKind, |
| 17 | IntegerLiteral: NumSuffix, |
| 18 | FloatLiteral: NumSuffix, |
| 25 | 19 | Bang, |
| 26 | 20 | BangEqual, |
| 27 | 21 | Pipe, |
| ... | ... | @@ -74,7 +68,10 @@ pub const Token = struct { |
| 74 | 68 | MultiLineComment, |
| 75 | 69 | Hash, |
| 76 | 70 | HashHash, |
| 77 | | }; |
| 71 | }, |
| 72 | start: usize, |
| 73 | end: usize, |
| 74 | source: *Source, |
| 78 | 75 | |
| 79 | 76 | pub const NumSuffix = enum { |
| 80 | 77 | None, |
| ... | ... | @@ -85,6 +82,14 @@ pub const Token = struct { |
| 85 | 82 | LL, |
| 86 | 83 | LLU, |
| 87 | 84 | }; |
| 85 | |
| 86 | pub const StrKind = enum { |
| 87 | None, |
| 88 | Wide, |
| 89 | Utf8, |
| 90 | Utf16, |
| 91 | Utf32, |
| 92 | }; |
| 88 | 93 | }; |
| 89 | 94 | |
| 90 | 95 | pub const Tokenizer = struct { |
| ... | ... | @@ -102,6 +107,10 @@ pub const Tokenizer = struct { |
| 102 | 107 | var state: enum { |
| 103 | 108 | Start, |
| 104 | 109 | Cr, |
| 110 | u, |
| 111 | u8, |
| 112 | U, |
| 113 | L, |
| 105 | 114 | StringLiteral, |
| 106 | 115 | CharLiteral, |
| 107 | 116 | EscapeSequence, |
| ... | ... | @@ -162,13 +171,23 @@ pub const Tokenizer = struct { |
| 162 | 171 | result.start = self.index + 1; |
| 163 | 172 | }, |
| 164 | 173 | '"' => { |
| 174 | result.id = .{ .StringLiteral = .None }; |
| 165 | 175 | state = .StringLiteral; |
| 166 | | result.id = .StringLiteral; |
| 167 | 176 | }, |
| 168 | 177 | '\'' => { |
| 178 | result.id = .{ .CharLiteral = .None }; |
| 169 | 179 | state = .CharLiteral; |
| 170 | 180 | }, |
| 171 | | 'a'...'z', 'A'...'Z', '_' => { |
| 181 | 'u' => { |
| 182 | state = .u; |
| 183 | }, |
| 184 | 'U' => { |
| 185 | state = .U; |
| 186 | }, |
| 187 | 'L' => { |
| 188 | state = .L; |
| 189 | }, |
| 190 | 'a'...'t', 'v'...'z', 'A'...'K', 'M'...'T', 'V'...'Z', '_' => { |
| 172 | 191 | state = .Identifier; |
| 173 | 192 | result.id = .Identifier; |
| 174 | 193 | }, |
| ... | ... | @@ -268,11 +287,9 @@ pub const Tokenizer = struct { |
| 268 | 287 | }, |
| 269 | 288 | '0' => { |
| 270 | 289 | state = .Zero; |
| 271 | | result.id = .IntegerLiteral; |
| 272 | 290 | }, |
| 273 | 291 | '1'...'9' => { |
| 274 | 292 | state = .IntegerLiteral; |
| 275 | | result.id = .IntegerLiteral; |
| 276 | 293 | }, |
| 277 | 294 | else => { |
| 278 | 295 | result.id = .Invalid; |
| ... | ... | @@ -291,14 +308,63 @@ pub const Tokenizer = struct { |
| 291 | 308 | break; |
| 292 | 309 | }, |
| 293 | 310 | }, |
| 294 | | // TODO l"" u"" U"" u8"" |
| 311 | .u => switch (c) { |
| 312 | '8' => { |
| 313 | state = .u8; |
| 314 | }, |
| 315 | '\'' => { |
| 316 | result.id = .{ .CharLiteral = .Utf16 }; |
| 317 | state = .CharLiteral; |
| 318 | }, |
| 319 | '\"' => { |
| 320 | result.id = .{ .StringLiteral = .Utf16 }; |
| 321 | state = .StringLiteral; |
| 322 | }, |
| 323 | else => { |
| 324 | state = .Identifier; |
| 325 | }, |
| 326 | }, |
| 327 | .u8 => switch (c) { |
| 328 | '\"' => { |
| 329 | result.id = .{ .StringLiteral = .Utf8 }; |
| 330 | state = .StringLiteral; |
| 331 | }, |
| 332 | else => { |
| 333 | state = .Identifier; |
| 334 | }, |
| 335 | }, |
| 336 | .U => switch (c) { |
| 337 | '\'' => { |
| 338 | result.id = .{ .CharLiteral = .Utf32 }; |
| 339 | state = .CharLiteral; |
| 340 | }, |
| 341 | '\"' => { |
| 342 | result.id = .{ .StringLiteral = .Utf32 }; |
| 343 | state = .StringLiteral; |
| 344 | }, |
| 345 | else => { |
| 346 | state = .Identifier; |
| 347 | }, |
| 348 | }, |
| 349 | .L => switch (c) { |
| 350 | '\'' => { |
| 351 | result.id = .{ .CharLiteral = .Wide }; |
| 352 | state = .CharLiteral; |
| 353 | }, |
| 354 | '\"' => { |
| 355 | result.id = .{ .StringLiteral = .Wide }; |
| 356 | state = .StringLiteral; |
| 357 | }, |
| 358 | else => { |
| 359 | state = .Identifier; |
| 360 | }, |
| 361 | }, |
| 295 | 362 | .StringLiteral => switch (c) { |
| 296 | 363 | '\\' => { |
| 297 | 364 | string = true; |
| 298 | 365 | state = .EscapeSequence; |
| 299 | 366 | }, |
| 300 | 367 | '"' => { |
| 301 | | result.id = .StringLiteral; |
| 302 | 368 | self.index += 1; |
| 303 | 369 | break; |
| 304 | 370 | }, |
| ... | ... | @@ -308,7 +374,6 @@ pub const Tokenizer = struct { |
| 308 | 374 | }, |
| 309 | 375 | else => {}, |
| 310 | 376 | }, |
| 311 | | // TODO l'' u'' U'' |
| 312 | 377 | .CharLiteral => switch (c) { |
| 313 | 378 | '\\' => { |
| 314 | 379 | string = false; |
| ... | ... | @@ -683,7 +748,7 @@ pub const Tokenizer = struct { |
| 683 | 748 | state = .IntegerSuffixL; |
| 684 | 749 | }, |
| 685 | 750 | else => { |
| 686 | | result.id = .IntegerLiteral; |
| 751 | result.id = .{ .IntegerLiteral = .None }; |
| 687 | 752 | break; |
| 688 | 753 | }, |
| 689 | 754 | }, |
| ... | ... | @@ -692,8 +757,7 @@ pub const Tokenizer = struct { |
| 692 | 757 | state = .IntegerSuffixUL; |
| 693 | 758 | }, |
| 694 | 759 | else => { |
| 695 | | result.id = .IntegerLiteral; |
| 696 | | result.num_suffix = .U; |
| 760 | result.id = .{ .IntegerLiteral = .U }; |
| 697 | 761 | break; |
| 698 | 762 | }, |
| 699 | 763 | }, |
| ... | ... | @@ -702,40 +766,34 @@ pub const Tokenizer = struct { |
| 702 | 766 | state = .IntegerSuffixLL; |
| 703 | 767 | }, |
| 704 | 768 | 'u', 'U' => { |
| 705 | | result.id = .IntegerLiteral; |
| 706 | | result.num_suffix = .LU; |
| 769 | result.id = .{ .IntegerLiteral = .LU }; |
| 707 | 770 | self.index += 1; |
| 708 | 771 | break; |
| 709 | 772 | }, |
| 710 | 773 | else => { |
| 711 | | result.id = .IntegerLiteral; |
| 712 | | result.num_suffix = .L; |
| 774 | result.id = .{ .IntegerLiteral = .L }; |
| 713 | 775 | break; |
| 714 | 776 | }, |
| 715 | 777 | }, |
| 716 | 778 | .IntegerSuffixLL => switch (c) { |
| 717 | 779 | 'u', 'U' => { |
| 718 | | result.id = .IntegerLiteral; |
| 719 | | result.num_suffix = .LLU; |
| 780 | result.id = .{ .IntegerLiteral = .LLU }; |
| 720 | 781 | self.index += 1; |
| 721 | 782 | break; |
| 722 | 783 | }, |
| 723 | 784 | else => { |
| 724 | | result.id = .IntegerLiteral; |
| 725 | | result.num_suffix = .LL; |
| 785 | result.id = .{ .IntegerLiteral = .LL }; |
| 726 | 786 | break; |
| 727 | 787 | }, |
| 728 | 788 | }, |
| 729 | 789 | .IntegerSuffixUL => switch (c) { |
| 730 | 790 | 'l', 'L' => { |
| 731 | | result.id = .IntegerLiteral; |
| 732 | | result.num_suffix = .LLU; |
| 791 | result.id = .{ .IntegerLiteral = .LLU }; |
| 733 | 792 | self.index += 1; |
| 734 | 793 | break; |
| 735 | 794 | }, |
| 736 | 795 | else => { |
| 737 | | result.id = .IntegerLiteral; |
| 738 | | result.num_suffix = .LU; |
| 796 | result.id = .{ .IntegerLiteral = .LU }; |
| 739 | 797 | break; |
| 740 | 798 | }, |
| 741 | 799 | }, |
| ... | ... | @@ -782,19 +840,17 @@ pub const Tokenizer = struct { |
| 782 | 840 | }, |
| 783 | 841 | .FloatSuffix => switch (c) { |
| 784 | 842 | 'l', 'L' => { |
| 785 | | result.id = .FloatLiteral; |
| 786 | | result.num_suffix = .L; |
| 843 | result.id = .{ .FloatLiteral = .L }; |
| 787 | 844 | self.index += 1; |
| 788 | 845 | break; |
| 789 | 846 | }, |
| 790 | 847 | 'f', 'F' => { |
| 791 | | result.id = .FloatLiteral; |
| 792 | | result.num_suffix = .F; |
| 848 | result.id = .{ .FloatLiteral = .F }; |
| 793 | 849 | self.index += 1; |
| 794 | 850 | break; |
| 795 | 851 | }, |
| 796 | 852 | else => { |
| 797 | | result.id = .FloatLiteral; |
| 853 | result.id = .{ .FloatLiteral = .None }; |
| 798 | 854 | break; |
| 799 | 855 | }, |
| 800 | 856 | }, |
| ... | ... | @@ -802,7 +858,7 @@ pub const Tokenizer = struct { |
| 802 | 858 | } else if (self.index == self.source.buffer.len) { |
| 803 | 859 | switch (state) { |
| 804 | 860 | .Start => {}, |
| 805 | | .Identifier => { |
| 861 | .u, .u8, .U, .L, .Identifier => { |
| 806 | 862 | result.id = .Identifier; |
| 807 | 863 | }, |
| 808 | 864 | |
| ... | ... | @@ -822,25 +878,19 @@ pub const Tokenizer = struct { |
| 822 | 878 | .FloatExponentDigits, |
| 823 | 879 | => result.id = .Invalid, |
| 824 | 880 | |
| 825 | | .IntegerLiteralOct, .IntegerLiteralBinary, .IntegerLiteralHex, .IntegerLiteral, .IntegerSuffix, .Zero => result.id = .IntegerLiteral, |
| 826 | | .IntegerSuffixU => { |
| 827 | | result.id = .IntegerLiteral; |
| 828 | | result.num_suffix = .U; |
| 829 | | }, |
| 830 | | .IntegerSuffixL => { |
| 831 | | result.id = .IntegerLiteral; |
| 832 | | result.num_suffix = .L; |
| 833 | | }, |
| 834 | | .IntegerSuffixLL => { |
| 835 | | result.id = .IntegerLiteral; |
| 836 | | result.num_suffix = .LL; |
| 837 | | }, |
| 838 | | .IntegerSuffixUL => { |
| 839 | | result.id = .IntegerLiteral; |
| 840 | | result.num_suffix = .LU; |
| 841 | | }, |
| 881 | .IntegerLiteralOct, |
| 882 | .IntegerLiteralBinary, |
| 883 | .IntegerLiteralHex, |
| 884 | .IntegerLiteral, |
| 885 | .IntegerSuffix, |
| 886 | .Zero, |
| 887 | => result.id = .{ .IntegerLiteral = .None }, |
| 888 | .IntegerSuffixU => result.id = .{ .IntegerLiteral = .U }, |
| 889 | .IntegerSuffixL => result.id = .{ .IntegerLiteral = .L }, |
| 890 | .IntegerSuffixLL => result.id = .{ .IntegerLiteral = .LL }, |
| 891 | .IntegerSuffixUL => result.id = .{ .IntegerLiteral = .LU }, |
| 842 | 892 | |
| 843 | | .FloatSuffix => result.id = .FloatLiteral, |
| 893 | .FloatSuffix => result.id = .{ .FloatLiteral = .None }, |
| 844 | 894 | .Equal => result.id = .Equal, |
| 845 | 895 | .Bang => result.id = .Bang, |
| 846 | 896 | .Minus => result.id = .Minus, |