| ... | ... | @@ -6,12 +6,12 @@ pub const Token = struct { |
| 6 | 6 | start: usize, |
| 7 | 7 | end: usize, |
| 8 | 8 | |
| 9 | | const Keyword = struct { |
| 9 | pub const Keyword = struct { |
| 10 | 10 | bytes: []const u8, |
| 11 | 11 | id: Id, |
| 12 | 12 | }; |
| 13 | 13 | |
| 14 | | const keywords = []Keyword { |
| 14 | pub const keywords = []Keyword { |
| 15 | 15 | Keyword{.bytes="align", .id = Id.Keyword_align}, |
| 16 | 16 | Keyword{.bytes="and", .id = Id.Keyword_and}, |
| 17 | 17 | Keyword{.bytes="asm", .id = Id.Keyword_asm}, |
| ... | ... | @@ -62,6 +62,7 @@ pub const Token = struct { |
| 62 | 62 | Keyword{.bytes="while", .id = Id.Keyword_while}, |
| 63 | 63 | }; |
| 64 | 64 | |
| 65 | // TODO perfect hash at comptime |
| 65 | 66 | fn getKeyword(bytes: []const u8) ?Id { |
| 66 | 67 | for (keywords) |kw| { |
| 67 | 68 | if (mem.eql(u8, kw.bytes, bytes)) { |
| ... | ... | @@ -236,10 +237,15 @@ pub const Tokenizer = struct { |
| 236 | 237 | Zero, |
| 237 | 238 | IntegerLiteral, |
| 238 | 239 | IntegerLiteralWithRadix, |
| 240 | IntegerLiteralWithRadixHex, |
| 239 | 241 | NumberDot, |
| 242 | NumberDotHex, |
| 240 | 243 | FloatFraction, |
| 244 | FloatFractionHex, |
| 241 | 245 | FloatExponentUnsigned, |
| 246 | FloatExponentUnsignedHex, |
| 242 | 247 | FloatExponentNumber, |
| 248 | FloatExponentNumberHex, |
| 243 | 249 | Ampersand, |
| 244 | 250 | Caret, |
| 245 | 251 | Percent, |
| ... | ... | @@ -839,9 +845,12 @@ pub const Tokenizer = struct { |
| 839 | 845 | else => self.checkLiteralCharacter(), |
| 840 | 846 | }, |
| 841 | 847 | State.Zero => switch (c) { |
| 842 | | 'b', 'o', 'x' => { |
| 848 | 'b', 'o' => { |
| 843 | 849 | state = State.IntegerLiteralWithRadix; |
| 844 | 850 | }, |
| 851 | 'x' => { |
| 852 | state = State.IntegerLiteralWithRadixHex; |
| 853 | }, |
| 845 | 854 | else => { |
| 846 | 855 | // reinterpret as a normal number |
| 847 | 856 | self.index -= 1; |
| ... | ... | @@ -862,8 +871,15 @@ pub const Tokenizer = struct { |
| 862 | 871 | '.' => { |
| 863 | 872 | state = State.NumberDot; |
| 864 | 873 | }, |
| 874 | '0'...'9' => {}, |
| 875 | else => break, |
| 876 | }, |
| 877 | State.IntegerLiteralWithRadixHex => switch (c) { |
| 878 | '.' => { |
| 879 | state = State.NumberDotHex; |
| 880 | }, |
| 865 | 881 | 'p', 'P' => { |
| 866 | | state = State.FloatExponentUnsigned; |
| 882 | state = State.FloatExponentUnsignedHex; |
| 867 | 883 | }, |
| 868 | 884 | '0'...'9', 'a'...'f', 'A'...'F' => {}, |
| 869 | 885 | else => break, |
| ... | ... | @@ -880,13 +896,32 @@ pub const Tokenizer = struct { |
| 880 | 896 | state = State.FloatFraction; |
| 881 | 897 | }, |
| 882 | 898 | }, |
| 899 | State.NumberDotHex => switch (c) { |
| 900 | '.' => { |
| 901 | self.index -= 1; |
| 902 | state = State.Start; |
| 903 | break; |
| 904 | }, |
| 905 | else => { |
| 906 | self.index -= 1; |
| 907 | result.id = Token.Id.FloatLiteral; |
| 908 | state = State.FloatFractionHex; |
| 909 | }, |
| 910 | }, |
| 883 | 911 | State.FloatFraction => switch (c) { |
| 884 | | 'p', 'P', 'e', 'E' => { |
| 912 | 'e', 'E' => { |
| 885 | 913 | state = State.FloatExponentUnsigned; |
| 886 | 914 | }, |
| 887 | 915 | '0'...'9' => {}, |
| 888 | 916 | else => break, |
| 889 | 917 | }, |
| 918 | State.FloatFractionHex => switch (c) { |
| 919 | 'p', 'P' => { |
| 920 | state = State.FloatExponentUnsignedHex; |
| 921 | }, |
| 922 | '0'...'9', 'a'...'f', 'A'...'F' => {}, |
| 923 | else => break, |
| 924 | }, |
| 890 | 925 | State.FloatExponentUnsigned => switch (c) { |
| 891 | 926 | '+', '-' => { |
| 892 | 927 | state = State.FloatExponentNumber; |
| ... | ... | @@ -897,7 +932,21 @@ pub const Tokenizer = struct { |
| 897 | 932 | state = State.FloatExponentNumber; |
| 898 | 933 | } |
| 899 | 934 | }, |
| 935 | State.FloatExponentUnsignedHex => switch (c) { |
| 936 | '+', '-' => { |
| 937 | state = State.FloatExponentNumberHex; |
| 938 | }, |
| 939 | else => { |
| 940 | // reinterpret as a normal exponent number |
| 941 | self.index -= 1; |
| 942 | state = State.FloatExponentNumberHex; |
| 943 | } |
| 944 | }, |
| 900 | 945 | State.FloatExponentNumber => switch (c) { |
| 946 | '0'...'9' => {}, |
| 947 | else => break, |
| 948 | }, |
| 949 | State.FloatExponentNumberHex => switch (c) { |
| 901 | 950 | '0'...'9', 'a'...'f', 'A'...'F' => {}, |
| 902 | 951 | else => break, |
| 903 | 952 | }, |
| ... | ... | @@ -908,8 +957,11 @@ pub const Tokenizer = struct { |
| 908 | 957 | State.C, |
| 909 | 958 | State.IntegerLiteral, |
| 910 | 959 | State.IntegerLiteralWithRadix, |
| 960 | State.IntegerLiteralWithRadixHex, |
| 911 | 961 | State.FloatFraction, |
| 962 | State.FloatFractionHex, |
| 912 | 963 | State.FloatExponentNumber, |
| 964 | State.FloatExponentNumberHex, |
| 913 | 965 | State.StringLiteral, // find this error later |
| 914 | 966 | State.MultilineStringLiteralLine, |
| 915 | 967 | State.Builtin => {}, |
| ... | ... | @@ -928,7 +980,9 @@ pub const Tokenizer = struct { |
| 928 | 980 | }, |
| 929 | 981 | |
| 930 | 982 | State.NumberDot, |
| 983 | State.NumberDotHex, |
| 931 | 984 | State.FloatExponentUnsigned, |
| 985 | State.FloatExponentUnsignedHex, |
| 932 | 986 | State.SawAtSign, |
| 933 | 987 | State.Backslash, |
| 934 | 988 | State.MultilineStringLiteralLineBackslash, |
| ... | ... | @@ -1073,7 +1127,7 @@ test "tokenizer" { |
| 1073 | 1127 | }); |
| 1074 | 1128 | } |
| 1075 | 1129 | |
| 1076 | | test "tokenizer - float literal" { |
| 1130 | test "tokenizer - float literal e exponent" { |
| 1077 | 1131 | testTokenize("a = 4.94065645841246544177e-324;\n", []Token.Id { |
| 1078 | 1132 | Token.Id.Identifier, |
| 1079 | 1133 | Token.Id.Equal, |
| ... | ... | @@ -1082,6 +1136,15 @@ test "tokenizer - float literal" { |
| 1082 | 1136 | }); |
| 1083 | 1137 | } |
| 1084 | 1138 | |
| 1139 | test "tokenizer - float literal p exponent" { |
| 1140 | testTokenize("a = 0x1.a827999fcef32p+1022;\n", []Token.Id { |
| 1141 | Token.Id.Identifier, |
| 1142 | Token.Id.Equal, |
| 1143 | Token.Id.FloatLiteral, |
| 1144 | Token.Id.Semicolon, |
| 1145 | }); |
| 1146 | } |
| 1147 | |
| 1085 | 1148 | test "tokenizer - chars" { |
| 1086 | 1149 | testTokenize("'c'", []Token.Id {Token.Id.CharLiteral}); |
| 1087 | 1150 | } |