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) {
121121 case CTokIdRParen:
122122 case CTokIdEOF:
123123 case CTokIdDot:
124 case CTokIdAsterisk:
125 case CTokIdBang:
126 case CTokIdTilde:
124127 break;
125128 }
126129}
......@@ -228,10 +231,22 @@ void tokenize_c_macro(CTokenize *ctok, const uint8_t *c) {
228231 begin_token(ctok, CTokIdRParen);
229232 end_token(ctok);
230233 break;
234 case '*':
235 begin_token(ctok, CTokIdAsterisk);
236 end_token(ctok);
237 break;
231238 case '-':
232239 begin_token(ctok, CTokIdMinus);
233240 end_token(ctok);
234241 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;
235250 default:
236251 return mark_error(ctok);
237252 }
src/c_tokenizer.hpp+3
......@@ -22,6 +22,9 @@ enum CTokId {
2222 CTokIdRParen,
2323 CTokIdEOF,
2424 CTokIdDot,
25 CTokIdAsterisk,
26 CTokIdBang,
27 CTokIdTilde,
2528};
2629
2730enum CNumLitSuffix {
src/translate_c.cpp+69-29
......@@ -4000,6 +4000,10 @@ static void render_macros(Context *c) {
40004000 }
40014001}
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
40034007static AstNode *parse_ctok_num_lit(Context *c, CTokenize *ctok, size_t *tok_i, bool negate) {
40044008 CTok *tok = &ctok->tokens.at(*tok_i);
40054009 if (tok->id == CTokIdNumLitInt) {
......@@ -4027,7 +4031,7 @@ static AstNode *parse_ctok_num_lit(Context *c, CTokenize *ctok, size_t *tok_i, b
40274031 return nullptr;
40284032}
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) {
40314035 CTok *tok = &ctok->tokens.at(*tok_i);
40324036 switch (tok->id) {
40334037 case CTokIdCharLit:
......@@ -4044,38 +4048,17 @@ static AstNode *parse_ctok(Context *c, CTokenize *ctok, size_t *tok_i) {
40444048 return parse_ctok_num_lit(c, ctok, tok_i, false);
40454049 case CTokIdSymbol:
40464050 {
4047 bool need_symbol = false;
4048 CTokId curr_id = CTokIdSymbol;
4051 *tok_i += 1;
40494052 Buf *symbol_name = buf_create_from_buf(&tok->data.symbol);
4050 AstNode *curr_node = 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;
4053 return trans_create_node_symbol(c, symbol_name);
40744054 }
40754055 case CTokIdLParen:
40764056 {
40774057 *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
40804063 CTok *next_tok = &ctok->tokens.at(*tok_i);
40814064 if (next_tok->id != CTokIdRParen) {
......@@ -4087,12 +4070,69 @@ static AstNode *parse_ctok(Context *c, CTokenize *ctok, size_t *tok_i) {
40874070 case CTokIdDot:
40884071 case CTokIdEOF:
40894072 case CTokIdRParen:
4073 case CTokIdAsterisk:
4074 case CTokIdBang:
4075 case CTokIdTilde:
40904076 // not able to make sense of this
40914077 return nullptr;
40924078 }
40934079 zig_unreachable();
40944080}
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
40964136static void process_macro(Context *c, CTokenize *ctok, Buf *name, const char *char_ptr) {
40974137 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
41054145 assert(name_tok->id == CTokIdSymbol && buf_eql_buf(&name_tok->data.symbol, name));
41064146 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);
41094149 if (result_node == nullptr) {
41104150 return;
41114151 }