authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-12-07 11:52:52-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-12-07 11:52:52-05:00
logdc502042d58ccfb3ad05d68c865a9079fe9015ec
treea14a5c8759dadce39008334c3ed986e07e1a9cf3
parent62c25af8021fc399c9a8c667dd986a458b40a7dd

translate-c: refactor prefix and suffix op C macro parsing


3 files changed, 87 insertions(+), 29 deletions(-)

src/c_tokenizer.cpp+15
...@@ -121,6 +121,9 @@ static void begin_token(CTokenize *ctok, CTokId id) {...@@ -121,6 +121,9 @@ static void begin_token(CTokenize *ctok, CTokId id) {
121 case CTokIdRParen:121 case CTokIdRParen:
122 case CTokIdEOF:122 case CTokIdEOF:
123 case CTokIdDot:123 case CTokIdDot:
124 case CTokIdAsterisk:
125 case CTokIdBang:
126 case CTokIdTilde:
124 break;127 break;
125 }128 }
126}129}
...@@ -228,10 +231,22 @@ void tokenize_c_macro(CTokenize *ctok, const uint8_t *c) {...@@ -228,10 +231,22 @@ void tokenize_c_macro(CTokenize *ctok, const uint8_t *c) {
228 begin_token(ctok, CTokIdRParen);231 begin_token(ctok, CTokIdRParen);
229 end_token(ctok);232 end_token(ctok);
230 break;233 break;
234 case '*':
235 begin_token(ctok, CTokIdAsterisk);
236 end_token(ctok);
237 break;
231 case '-':238 case '-':
232 begin_token(ctok, CTokIdMinus);239 begin_token(ctok, CTokIdMinus);
233 end_token(ctok);240 end_token(ctok);
234 break;241 break;
242 case '!':
243 begin_token(ctok, CTokIdBang);
244 end_token(ctok);
245 break;
246 case '~':
247 begin_token(ctok, CTokIdTilde);
248 end_token(ctok);
249 break;
235 default:250 default:
236 return mark_error(ctok);251 return mark_error(ctok);
237 }252 }
src/c_tokenizer.hpp+3
...@@ -22,6 +22,9 @@ enum CTokId {...@@ -22,6 +22,9 @@ enum CTokId {
22 CTokIdRParen,22 CTokIdRParen,
23 CTokIdEOF,23 CTokIdEOF,
24 CTokIdDot,24 CTokIdDot,
25 CTokIdAsterisk,
26 CTokIdBang,
27 CTokIdTilde,
25};28};
2629
27enum CNumLitSuffix {30enum CNumLitSuffix {
src/translate_c.cpp+69-29
...@@ -4000,6 +4000,10 @@ static void render_macros(Context *c) {...@@ -4000,6 +4000,10 @@ static void render_macros(Context *c) {
4000 }4000 }
4001}4001}
40024002
4003static AstNode *parse_ctok_primary_expr(Context *c, CTokenize *ctok, size_t *tok_i);
4004static AstNode *parse_ctok_expr(Context *c, CTokenize *ctok, size_t *tok_i);
4005static AstNode *parse_ctok_prefix_op_expr(Context *c, CTokenize *ctok, size_t *tok_i);
4006
4003static AstNode *parse_ctok_num_lit(Context *c, CTokenize *ctok, size_t *tok_i, bool negate) {4007static AstNode *parse_ctok_num_lit(Context *c, CTokenize *ctok, size_t *tok_i, bool negate) {
4004 CTok *tok = &ctok->tokens.at(*tok_i);4008 CTok *tok = &ctok->tokens.at(*tok_i);
4005 if (tok->id == CTokIdNumLitInt) {4009 if (tok->id == CTokIdNumLitInt) {
...@@ -4027,7 +4031,7 @@ static AstNode *parse_ctok_num_lit(Context *c, CTokenize *ctok, size_t *tok_i, b...@@ -4027,7 +4031,7 @@ static AstNode *parse_ctok_num_lit(Context *c, CTokenize *ctok, size_t *tok_i, b
4027 return nullptr;4031 return nullptr;
4028}4032}
40294033
4030static AstNode *parse_ctok(Context *c, CTokenize *ctok, size_t *tok_i) {4034static AstNode *parse_ctok_primary_expr(Context *c, CTokenize *ctok, size_t *tok_i) {
4031 CTok *tok = &ctok->tokens.at(*tok_i);4035 CTok *tok = &ctok->tokens.at(*tok_i);
4032 switch (tok->id) {4036 switch (tok->id) {
4033 case CTokIdCharLit:4037 case CTokIdCharLit:
...@@ -4044,38 +4048,17 @@ static AstNode *parse_ctok(Context *c, CTokenize *ctok, size_t *tok_i) {...@@ -4044,38 +4048,17 @@ static AstNode *parse_ctok(Context *c, CTokenize *ctok, size_t *tok_i) {
4044 return parse_ctok_num_lit(c, ctok, tok_i, false);4048 return parse_ctok_num_lit(c, ctok, tok_i, false);
4045 case CTokIdSymbol:4049 case CTokIdSymbol:
4046 {4050 {
4047 bool need_symbol = false;4051 *tok_i += 1;
4048 CTokId curr_id = CTokIdSymbol;
4049 Buf *symbol_name = buf_create_from_buf(&tok->data.symbol);4052 Buf *symbol_name = buf_create_from_buf(&tok->data.symbol);
4050 AstNode *curr_node = trans_create_node_symbol(c, symbol_name);4053 return trans_create_node_symbol(c, symbol_name);
4051 AstNode *parent_node = curr_node;
4052 do {
4053 *tok_i += 1;
4054 CTok* curr_tok = &ctok->tokens.at(*tok_i);
4055 if (need_symbol) {
4056 if (curr_tok->id == CTokIdSymbol) {
4057 symbol_name = buf_create_from_buf(&curr_tok->data.symbol);
4058 curr_node = trans_create_node_field_access(c, parent_node, buf_create_from_buf(symbol_name));
4059 parent_node = curr_node;
4060 need_symbol = false;
4061 } else {
4062 return nullptr;
4063 }
4064 } else {
4065 if (curr_tok->id == CTokIdDot) {
4066 need_symbol = true;
4067 continue;
4068 } else {
4069 break;
4070 }
4071 }
4072 } while (curr_id != CTokIdEOF);
4073 return curr_node;
4074 }4054 }
4075 case CTokIdLParen:4055 case CTokIdLParen:
4076 {4056 {
4077 *tok_i += 1;4057 *tok_i += 1;
4078 AstNode *inner_node = parse_ctok(c, ctok, tok_i);4058 AstNode *inner_node = parse_ctok_expr(c, ctok, tok_i);
4059 if (inner_node == nullptr) {
4060 return nullptr;
4061 }
40794062
4080 CTok *next_tok = &ctok->tokens.at(*tok_i);4063 CTok *next_tok = &ctok->tokens.at(*tok_i);
4081 if (next_tok->id != CTokIdRParen) {4064 if (next_tok->id != CTokIdRParen) {
...@@ -4087,12 +4070,69 @@ static AstNode *parse_ctok(Context *c, CTokenize *ctok, size_t *tok_i) {...@@ -4087,12 +4070,69 @@ static AstNode *parse_ctok(Context *c, CTokenize *ctok, size_t *tok_i) {
4087 case CTokIdDot:4070 case CTokIdDot:
4088 case CTokIdEOF:4071 case CTokIdEOF:
4089 case CTokIdRParen:4072 case CTokIdRParen:
4073 case CTokIdAsterisk:
4074 case CTokIdBang:
4075 case CTokIdTilde:
4090 // not able to make sense of this4076 // not able to make sense of this
4091 return nullptr;4077 return nullptr;
4092 }4078 }
4093 zig_unreachable();4079 zig_unreachable();
4094}4080}
40954081
4082static AstNode *parse_ctok_expr(Context *c, CTokenize *ctok, size_t *tok_i) {
4083 return parse_ctok_prefix_op_expr(c, ctok, tok_i);
4084}
4085
4086static AstNode *parse_ctok_suffix_op_expr(Context *c, CTokenize *ctok, size_t *tok_i) {
4087 AstNode *node = parse_ctok_primary_expr(c, ctok, tok_i);
4088 if (node == nullptr)
4089 return nullptr;
4090
4091 while (true) {
4092 CTok *first_tok = &ctok->tokens.at(*tok_i);
4093 if (first_tok->id == CTokIdDot) {
4094 *tok_i += 1;
4095
4096 CTok *name_tok = &ctok->tokens.at(*tok_i);
4097 if (name_tok->id != CTokIdSymbol) {
4098 return nullptr;
4099 }
4100 *tok_i += 1;
4101
4102 node = trans_create_node_field_access(c, node, buf_create_from_buf(&name_tok->data.symbol));
4103 } else if (first_tok->id == CTokIdAsterisk) {
4104 *tok_i += 1;
4105
4106 node = trans_create_node_addr_of(c, false, false, node);
4107 } else {
4108 return node;
4109 }
4110 }
4111}
4112
4113static PrefixOp ctok_to_prefix_op(CTok *token) {
4114 switch (token->id) {
4115 case CTokIdBang: return PrefixOpBoolNot;
4116 case CTokIdMinus: return PrefixOpNegation;
4117 case CTokIdTilde: return PrefixOpBinNot;
4118 case CTokIdAsterisk: return PrefixOpDereference;
4119 default: return PrefixOpInvalid;
4120 }
4121}
4122static AstNode *parse_ctok_prefix_op_expr(Context *c, CTokenize *ctok, size_t *tok_i) {
4123 CTok *op_tok = &ctok->tokens.at(*tok_i);
4124 PrefixOp prefix_op = ctok_to_prefix_op(op_tok);
4125 if (prefix_op == PrefixOpInvalid) {
4126 return parse_ctok_suffix_op_expr(c, ctok, tok_i);
4127 }
4128 *tok_i += 1;
4129
4130 AstNode *prefix_op_expr = parse_ctok_prefix_op_expr(c, ctok, tok_i);
4131 if (prefix_op_expr == nullptr)
4132 return nullptr;
4133 return trans_create_node_prefix_op(c, prefix_op, prefix_op_expr);
4134}
4135
4096static void process_macro(Context *c, CTokenize *ctok, Buf *name, const char *char_ptr) {4136static void process_macro(Context *c, CTokenize *ctok, Buf *name, const char *char_ptr) {
4097 tokenize_c_macro(ctok, (const uint8_t *)char_ptr);4137 tokenize_c_macro(ctok, (const uint8_t *)char_ptr);
40984138
...@@ -4105,7 +4145,7 @@ static void process_macro(Context *c, CTokenize *ctok, Buf *name, const char *ch...@@ -4105,7 +4145,7 @@ static void process_macro(Context *c, CTokenize *ctok, Buf *name, const char *ch
4105 assert(name_tok->id == CTokIdSymbol && buf_eql_buf(&name_tok->data.symbol, name));4145 assert(name_tok->id == CTokIdSymbol && buf_eql_buf(&name_tok->data.symbol, name));
4106 tok_i += 1;4146 tok_i += 1;
41074147
4108 AstNode *result_node = parse_ctok(c, ctok, &tok_i);4148 AstNode *result_node = parse_ctok_suffix_op_expr(c, ctok, &tok_i);
4109 if (result_node == nullptr) {4149 if (result_node == nullptr) {
4110 return;4150 return;
4111 }4151 }