authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-05-09 12:48:38-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-05-09 12:48:38-04:00
logeb65410b624d3aa8c56e7f2d2e68502030f8e981
tree10ca4c149ed0918531b9e73cf7045fe224707e99
parent62065a9aea1c3c93cfea617403b7d5dc8344e36a
signaturelock-open Commit is signed but in an unrecognized format.

translate-c: enough C tokenization/parsing to handle shifting in macros

See #2451

4 files changed, 37 insertions(+), 0 deletions(-)

src/c_tokenizer.cpp+19
......@@ -124,6 +124,8 @@ static void begin_token(CTokenize *ctok, CTokId id) {
124124 case CTokIdAsterisk:
125125 case CTokIdBang:
126126 case CTokIdTilde:
127 case CTokIdShl:
128 case CTokIdLt:
127129 break;
128130 }
129131}
......@@ -223,6 +225,10 @@ void tokenize_c_macro(CTokenize *ctok, const uint8_t *c) {
223225 begin_token(ctok, CTokIdDot);
224226 end_token(ctok);
225227 break;
228 case '<':
229 begin_token(ctok, CTokIdLt);
230 ctok->state = CTokStateGotLt;
231 break;
226232 case '(':
227233 begin_token(ctok, CTokIdLParen);
228234 end_token(ctok);
......@@ -251,6 +257,18 @@ void tokenize_c_macro(CTokenize *ctok, const uint8_t *c) {
251257 return mark_error(ctok);
252258 }
253259 break;
260 case CTokStateGotLt:
261 switch (*c) {
262 case '<':
263 ctok->cur_tok->id = CTokIdShl;
264 end_token(ctok);
265 ctok->state = CTokStateStart;
266 break;
267 default:
268 ctok->state = CTokStateStart;
269 continue;
270 }
271 break;
254272 case CTokStateFloat:
255273 switch (*c) {
256274 case '.':
......@@ -791,6 +809,7 @@ found_end_of_macro:
791809 case CTokStateNumLitIntSuffixL:
792810 case CTokStateNumLitIntSuffixUL:
793811 case CTokStateNumLitIntSuffixLL:
812 case CTokStateGotLt:
794813 end_token(ctok);
795814 break;
796815 case CTokStateFloat:
src/c_tokenizer.hpp+3
......@@ -25,6 +25,8 @@ enum CTokId {
2525 CTokIdAsterisk,
2626 CTokIdBang,
2727 CTokIdTilde,
28 CTokIdShl,
29 CTokIdLt,
2830};
2931
3032enum CNumLitSuffix {
......@@ -78,6 +80,7 @@ enum CTokState {
7880 CTokStateNumLitIntSuffixL,
7981 CTokStateNumLitIntSuffixLL,
8082 CTokStateNumLitIntSuffixUL,
83 CTokStateGotLt,
8184};
8285
8386struct CTokenize {
src/translate_c.cpp+9
......@@ -4922,6 +4922,8 @@ static AstNode *parse_ctok_primary_expr(Context *c, CTokenize *ctok, size_t *tok
49224922 case CTokIdAsterisk:
49234923 case CTokIdBang:
49244924 case CTokIdTilde:
4925 case CTokIdShl:
4926 case CTokIdLt:
49254927 // not able to make sense of this
49264928 return nullptr;
49274929 }
......@@ -4953,6 +4955,13 @@ static AstNode *parse_ctok_suffix_op_expr(Context *c, CTokenize *ctok, size_t *t
49534955 *tok_i += 1;
49544956
49554957 node = trans_create_node_ptr_type(c, false, false, node, PtrLenC);
4958 } else if (first_tok->id == CTokIdShl) {
4959 *tok_i += 1;
4960
4961 AstNode *rhs_node = parse_ctok_expr(c, ctok, tok_i);
4962 if (rhs_node == nullptr)
4963 return nullptr;
4964 node = trans_create_node_bin_op(c, node, BinOpTypeBitShiftLeft, rhs_node);
49564965 } else {
49574966 return node;
49584967 }
test/translate_c.zig+6
......@@ -2,6 +2,12 @@ const tests = @import("tests.zig");
22const builtin = @import("builtin");
33
44pub fn addCases(cases: *tests.TranslateCContext) void {
5 cases.add("macro with left shift",
6 \\#define REDISMODULE_READ (1<<0)
7 ,
8 \\pub const REDISMODULE_READ = 1 << 0;
9 );
10
511 cases.add("casting pointers to ints and ints to pointers",
612 \\void foo(void);
713 \\void bar(void) {