| ... | @@ -124,7 +124,7 @@ pub const Token = struct { | ... | @@ -124,7 +124,7 @@ pub const Token = struct { |
| 124 | Keyword_static_assert, | 124 | Keyword_static_assert, |
| 125 | Keyword_thread_local, | 125 | Keyword_thread_local, |
| 126 | | 126 | |
| 127 | // Preprocessor | 127 | // Preprocessor directives |
| 128 | Keyword_include, | 128 | Keyword_include, |
| 129 | Keyword_define, | 129 | Keyword_define, |
| 130 | Keyword_ifdef, | 130 | Keyword_ifdef, |
| ... | @@ -199,7 +199,7 @@ pub const Token = struct { | ... | @@ -199,7 +199,7 @@ pub const Token = struct { |
| 199 | Keyword.init("_Static_assert", .Keyword_static_assert), | 199 | Keyword.init("_Static_assert", .Keyword_static_assert), |
| 200 | Keyword.init("_Thread_local", .Keyword_thread_local), | 200 | Keyword.init("_Thread_local", .Keyword_thread_local), |
| 201 | | 201 | |
| 202 | // Preprocessor | 202 | // Preprocessor directives |
| 203 | Keyword.init("include", .Keyword_include), | 203 | Keyword.init("include", .Keyword_include), |
| 204 | Keyword.init("define", .Keyword_define), | 204 | Keyword.init("define", .Keyword_define), |
| 205 | Keyword.init("ifdef", .Keyword_ifdef), | 205 | Keyword.init("ifdef", .Keyword_ifdef), |
| ... | @@ -209,7 +209,7 @@ pub const Token = struct { | ... | @@ -209,7 +209,7 @@ pub const Token = struct { |
| 209 | }; | 209 | }; |
| 210 | | 210 | |
| 211 | // TODO perfect hash at comptime | 211 | // TODO perfect hash at comptime |
| 212 | pub fn getKeyword(bytes: []const u8, macro: bool) ?Id { | 212 | pub fn getKeyword(bytes: []const u8, pp_directive: bool) ?Id { |
| 213 | var hash = std.hash_map.hashString(bytes); | 213 | var hash = std.hash_map.hashString(bytes); |
| 214 | for (keywords) |kw| { | 214 | for (keywords) |kw| { |
| 215 | if (kw.hash == hash and mem.eql(u8, kw.bytes, bytes)) { | 215 | if (kw.hash == hash and mem.eql(u8, kw.bytes, bytes)) { |
| ... | @@ -220,7 +220,7 @@ pub const Token = struct { | ... | @@ -220,7 +220,7 @@ pub const Token = struct { |
| 220 | .Keyword_ifndef, | 220 | .Keyword_ifndef, |
| 221 | .Keyword_error, | 221 | .Keyword_error, |
| 222 | .Keyword_pragma, | 222 | .Keyword_pragma, |
| 223 | => if (!macro) return null, | 223 | => if (!pp_directive) return null, |
| 224 | else => {}, | 224 | else => {}, |
| 225 | } | 225 | } |
| 226 | return kw.id; | 226 | return kw.id; |
| ... | @@ -252,6 +252,7 @@ pub const Tokenizer = struct { | ... | @@ -252,6 +252,7 @@ pub const Tokenizer = struct { |
| 252 | source: *Source, | 252 | source: *Source, |
| 253 | index: usize = 0, | 253 | index: usize = 0, |
| 254 | prev_tok_id: @TagType(Token.Id) = .Invalid, | 254 | prev_tok_id: @TagType(Token.Id) = .Invalid, |
| | 255 | pp_directive: bool = false, |
| 255 | | 256 | |
| 256 | pub fn next(self: *Tokenizer) Token { | 257 | pub fn next(self: *Tokenizer) Token { |
| 257 | const start_index = self.index; | 258 | const start_index = self.index; |
| ... | @@ -321,11 +322,20 @@ pub const Tokenizer = struct { | ... | @@ -321,11 +322,20 @@ pub const Tokenizer = struct { |
| 321 | switch (state) { | 322 | switch (state) { |
| 322 | .Start => switch (c) { | 323 | .Start => switch (c) { |
| 323 | '\n' => { | 324 | '\n' => { |
| | 325 | if (!self.pp_directive) { |
| | 326 | result.start = self.index + 1; |
| | 327 | continue; |
| | 328 | } |
| | 329 | self.pp_directive = false; |
| 324 | result.id = .Nl; | 330 | result.id = .Nl; |
| 325 | self.index += 1; | 331 | self.index += 1; |
| 326 | break; | 332 | break; |
| 327 | }, | 333 | }, |
| 328 | '\r' => { | 334 | '\r' => { |
| | 335 | if (!self.pp_directive) { |
| | 336 | result.start = self.index + 1; |
| | 337 | continue; |
| | 338 | } |
| 329 | state = .Cr; | 339 | state = .Cr; |
| 330 | }, | 340 | }, |
| 331 | '"' => { | 341 | '"' => { |
| ... | @@ -460,6 +470,7 @@ pub const Tokenizer = struct { | ... | @@ -460,6 +470,7 @@ pub const Tokenizer = struct { |
| 460 | }, | 470 | }, |
| 461 | .Cr => switch (c) { | 471 | .Cr => switch (c) { |
| 462 | '\n' => { | 472 | '\n' => { |
| | 473 | self.pp_directive = false; |
| 463 | result.id = .Nl; | 474 | result.id = .Nl; |
| 464 | self.index += 1; | 475 | self.index += 1; |
| 465 | break; | 476 | break; |
| ... | @@ -603,7 +614,9 @@ pub const Tokenizer = struct { | ... | @@ -603,7 +614,9 @@ pub const Tokenizer = struct { |
| 603 | .Identifier => switch (c) { | 614 | .Identifier => switch (c) { |
| 604 | 'a'...'z', 'A'...'Z', '_', '0'...'9' => {}, | 615 | 'a'...'z', 'A'...'Z', '_', '0'...'9' => {}, |
| 605 | else => { | 616 | else => { |
| 606 | result.id = Token.getKeyword(self.source.buffer[result.start..self.index], self.prev_tok_id == .Hash) orelse .Identifier; | 617 | result.id = Token.getKeyword(self.source.buffer[result.start..self.index], self.prev_tok_id == .Hash and !self.pp_directive) orelse .Identifier; |
| | 618 | if (self.prev_tok_id == .Hash) |
| | 619 | self.pp_directive = true; |
| 607 | break; | 620 | break; |
| 608 | }, | 621 | }, |
| 609 | }, | 622 | }, |
| ... | @@ -1039,7 +1052,7 @@ pub const Tokenizer = struct { | ... | @@ -1039,7 +1052,7 @@ pub const Tokenizer = struct { |
| 1039 | switch (state) { | 1052 | switch (state) { |
| 1040 | .Start => {}, | 1053 | .Start => {}, |
| 1041 | .u, .u8, .U, .L, .Identifier => { | 1054 | .u, .u8, .U, .L, .Identifier => { |
| 1042 | result.id = Token.getKeyword(self.source.buffer[result.start..self.index], self.prev_tok_id == .Hash) orelse .Identifier; | 1055 | result.id = Token.getKeyword(self.source.buffer[result.start..self.index], self.prev_tok_id == .Hash and !self.pp_directive) orelse .Identifier; |
| 1043 | }, | 1056 | }, |
| 1044 | | 1057 | |
| 1045 | .Cr, | 1058 | .Cr, |
| ... | @@ -1116,8 +1129,6 @@ test "operators" { | ... | @@ -1116,8 +1129,6 @@ test "operators" { |
| 1116 | .PipeEqual, | 1129 | .PipeEqual, |
| 1117 | .Equal, | 1130 | .Equal, |
| 1118 | .EqualEqual, | 1131 | .EqualEqual, |
| 1119 | .Nl, | | |
| 1120 | | | |
| 1121 | .LParen, | 1132 | .LParen, |
| 1122 | .RParen, | 1133 | .RParen, |
| 1123 | .LBrace, | 1134 | .LBrace, |
| ... | @@ -1128,8 +1139,6 @@ test "operators" { | ... | @@ -1128,8 +1139,6 @@ test "operators" { |
| 1128 | .Period, | 1139 | .Period, |
| 1129 | .Period, | 1140 | .Period, |
| 1130 | .Ellipsis, | 1141 | .Ellipsis, |
| 1131 | .Nl, | | |
| 1132 | | | |
| 1133 | .Caret, | 1142 | .Caret, |
| 1134 | .CaretEqual, | 1143 | .CaretEqual, |
| 1135 | .Plus, | 1144 | .Plus, |
| ... | @@ -1138,8 +1147,6 @@ test "operators" { | ... | @@ -1138,8 +1147,6 @@ test "operators" { |
| 1138 | .Minus, | 1147 | .Minus, |
| 1139 | .MinusMinus, | 1148 | .MinusMinus, |
| 1140 | .MinusEqual, | 1149 | .MinusEqual, |
| 1141 | .Nl, | | |
| 1142 | | | |
| 1143 | .Asterisk, | 1150 | .Asterisk, |
| 1144 | .AsteriskEqual, | 1151 | .AsteriskEqual, |
| 1145 | .Percent, | 1152 | .Percent, |
| ... | @@ -1149,8 +1156,6 @@ test "operators" { | ... | @@ -1149,8 +1156,6 @@ test "operators" { |
| 1149 | .Semicolon, | 1156 | .Semicolon, |
| 1150 | .Slash, | 1157 | .Slash, |
| 1151 | .SlashEqual, | 1158 | .SlashEqual, |
| 1152 | .Nl, | | |
| 1153 | | | |
| 1154 | .Comma, | 1159 | .Comma, |
| 1155 | .Ampersand, | 1160 | .Ampersand, |
| 1156 | .AmpersandAmpersand, | 1161 | .AmpersandAmpersand, |
| ... | @@ -1159,8 +1164,6 @@ test "operators" { | ... | @@ -1159,8 +1164,6 @@ test "operators" { |
| 1159 | .AngleBracketLeft, | 1164 | .AngleBracketLeft, |
| 1160 | .AngleBracketLeftEqual, | 1165 | .AngleBracketLeftEqual, |
| 1161 | .AngleBracketAngleBracketLeft, | 1166 | .AngleBracketAngleBracketLeft, |
| 1162 | .Nl, | | |
| 1163 | | | |
| 1164 | .AngleBracketAngleBracketLeftEqual, | 1167 | .AngleBracketAngleBracketLeftEqual, |
| 1165 | .AngleBracketRight, | 1168 | .AngleBracketRight, |
| 1166 | .AngleBracketRightEqual, | 1169 | .AngleBracketRightEqual, |
| ... | @@ -1169,7 +1172,6 @@ test "operators" { | ... | @@ -1169,7 +1172,6 @@ test "operators" { |
| 1169 | .Tilde, | 1172 | .Tilde, |
| 1170 | .Hash, | 1173 | .Hash, |
| 1171 | .HashHash, | 1174 | .HashHash, |
| 1172 | .Nl, | | |
| 1173 | }, | 1175 | }, |
| 1174 | ); | 1176 | ); |
| 1175 | } | 1177 | } |
| ... | @@ -1192,8 +1194,6 @@ test "keywords" { | ... | @@ -1192,8 +1194,6 @@ test "keywords" { |
| 1192 | .Keyword_continue, | 1194 | .Keyword_continue, |
| 1193 | .Keyword_default, | 1195 | .Keyword_default, |
| 1194 | .Keyword_do, | 1196 | .Keyword_do, |
| 1195 | .Nl, | | |
| 1196 | | | |
| 1197 | .Keyword_double, | 1197 | .Keyword_double, |
| 1198 | .Keyword_else, | 1198 | .Keyword_else, |
| 1199 | .Keyword_enum, | 1199 | .Keyword_enum, |
| ... | @@ -1203,8 +1203,6 @@ test "keywords" { | ... | @@ -1203,8 +1203,6 @@ test "keywords" { |
| 1203 | .Keyword_goto, | 1203 | .Keyword_goto, |
| 1204 | .Keyword_if, | 1204 | .Keyword_if, |
| 1205 | .Keyword_int, | 1205 | .Keyword_int, |
| 1206 | .Nl, | | |
| 1207 | | | |
| 1208 | .Keyword_long, | 1206 | .Keyword_long, |
| 1209 | .Keyword_register, | 1207 | .Keyword_register, |
| 1210 | .Keyword_return, | 1208 | .Keyword_return, |
| ... | @@ -1212,8 +1210,6 @@ test "keywords" { | ... | @@ -1212,8 +1210,6 @@ test "keywords" { |
| 1212 | .Keyword_signed, | 1210 | .Keyword_signed, |
| 1213 | .Keyword_sizeof, | 1211 | .Keyword_sizeof, |
| 1214 | .Keyword_static, | 1212 | .Keyword_static, |
| 1215 | .Nl, | | |
| 1216 | | | |
| 1217 | .Keyword_struct, | 1213 | .Keyword_struct, |
| 1218 | .Keyword_switch, | 1214 | .Keyword_switch, |
| 1219 | .Keyword_typedef, | 1215 | .Keyword_typedef, |
| ... | @@ -1221,8 +1217,6 @@ test "keywords" { | ... | @@ -1221,8 +1217,6 @@ test "keywords" { |
| 1221 | .Keyword_unsigned, | 1217 | .Keyword_unsigned, |
| 1222 | .Keyword_void, | 1218 | .Keyword_void, |
| 1223 | .Keyword_volatile, | 1219 | .Keyword_volatile, |
| 1224 | .Nl, | | |
| 1225 | | | |
| 1226 | .Keyword_while, | 1220 | .Keyword_while, |
| 1227 | .Keyword_bool, | 1221 | .Keyword_bool, |
| 1228 | .Keyword_complex, | 1222 | .Keyword_complex, |
| ... | @@ -1230,22 +1224,19 @@ test "keywords" { | ... | @@ -1230,22 +1224,19 @@ test "keywords" { |
| 1230 | .Keyword_inline, | 1224 | .Keyword_inline, |
| 1231 | .Keyword_restrict, | 1225 | .Keyword_restrict, |
| 1232 | .Keyword_alignas, | 1226 | .Keyword_alignas, |
| 1233 | .Nl, | | |
| 1234 | | | |
| 1235 | .Keyword_alignof, | 1227 | .Keyword_alignof, |
| 1236 | .Keyword_atomic, | 1228 | .Keyword_atomic, |
| 1237 | .Keyword_generic, | 1229 | .Keyword_generic, |
| 1238 | .Keyword_noreturn, | 1230 | .Keyword_noreturn, |
| 1239 | .Keyword_static_assert, | 1231 | .Keyword_static_assert, |
| 1240 | .Keyword_thread_local, | 1232 | .Keyword_thread_local, |
| 1241 | .Nl, | | |
| 1242 | }); | 1233 | }); |
| 1243 | } | 1234 | } |
| 1244 | | 1235 | |
| 1245 | test "preprocessor keywords" { | 1236 | test "preprocessor keywords" { |
| 1246 | expectTokens( | 1237 | expectTokens( |
| 1247 | \\#include <test> | 1238 | \\#include <test> |
| 1248 | \\#define | 1239 | \\#define #include <1 |
| 1249 | \\#ifdef | 1240 | \\#ifdef |
| 1250 | \\#ifndef | 1241 | \\#ifndef |
| 1251 | \\#error | 1242 | \\#error |
| ... | @@ -1258,6 +1249,10 @@ test "preprocessor keywords" { | ... | @@ -1258,6 +1249,10 @@ test "preprocessor keywords" { |
| 1258 | .Nl, | 1249 | .Nl, |
| 1259 | .Hash, | 1250 | .Hash, |
| 1260 | .Keyword_define, | 1251 | .Keyword_define, |
| | 1252 | .Hash, |
| | 1253 | .Identifier, |
| | 1254 | .AngleBracketLeft, |
| | 1255 | .{ .IntegerLiteral = .None }, |
| 1261 | .Nl, | 1256 | .Nl, |
| 1262 | .Hash, | 1257 | .Hash, |
| 1263 | .Keyword_ifdef, | 1258 | .Keyword_ifdef, |