authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-12-07 14:22:41-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-12-07 14:22:41-05:00
log0dd3bbf6e8deba576ac7130354e3d1a7f20e7310
tree332af7f54ce268425aa80bcf85dcf178bb288936
parent37fbf01755ad8a87e9ffa5b2cd6592b523da0d8e
parent182cf5b8de375080bff6f2bb91cd398e776da16c

Merge branch 'master' into self-hosted


5 files changed, 122 insertions(+), 35 deletions(-)

src/ast_render.cpp+6-2
...@@ -584,12 +584,15 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {...@@ -584,12 +584,15 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {
584 PrefixOp op = node->data.prefix_op_expr.prefix_op;584 PrefixOp op = node->data.prefix_op_expr.prefix_op;
585 fprintf(ar->f, "%s", prefix_op_str(op));585 fprintf(ar->f, "%s", prefix_op_str(op));
586586
587 render_node_ungrouped(ar, node->data.prefix_op_expr.primary_expr);587 AstNode *child_node = node->data.prefix_op_expr.primary_expr;
588 bool new_grouped = child_node->type == NodeTypePrefixOpExpr || child_node->type == NodeTypeAddrOfExpr;
589 render_node_extra(ar, child_node, new_grouped);
588 if (!grouped) fprintf(ar->f, ")");590 if (!grouped) fprintf(ar->f, ")");
589 break;591 break;
590 }592 }
591 case NodeTypeAddrOfExpr:593 case NodeTypeAddrOfExpr:
592 {594 {
595 if (!grouped) fprintf(ar->f, "(");
593 fprintf(ar->f, "&");596 fprintf(ar->f, "&");
594 if (node->data.addr_of_expr.align_expr != nullptr) {597 if (node->data.addr_of_expr.align_expr != nullptr) {
595 fprintf(ar->f, "align(");598 fprintf(ar->f, "align(");
...@@ -617,6 +620,7 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {...@@ -617,6 +620,7 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {
617 }620 }
618621
619 render_node_ungrouped(ar, node->data.addr_of_expr.op_expr);622 render_node_ungrouped(ar, node->data.addr_of_expr.op_expr);
623 if (!grouped) fprintf(ar->f, ")");
620 break;624 break;
621 }625 }
622 case NodeTypeFnCallExpr:626 case NodeTypeFnCallExpr:
...@@ -625,7 +629,7 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {...@@ -625,7 +629,7 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {
625 fprintf(ar->f, "@");629 fprintf(ar->f, "@");
626 }630 }
627 AstNode *fn_ref_node = node->data.fn_call_expr.fn_ref_expr;631 AstNode *fn_ref_node = node->data.fn_call_expr.fn_ref_expr;
628 bool grouped = (fn_ref_node->type != NodeTypePrefixOpExpr);632 bool grouped = (fn_ref_node->type != NodeTypePrefixOpExpr && fn_ref_node->type != NodeTypeAddrOfExpr);
629 render_node_extra(ar, fn_ref_node, grouped);633 render_node_extra(ar, fn_ref_node, grouped);
630 fprintf(ar->f, "(");634 fprintf(ar->f, "(");
631 for (size_t i = 0; i < node->data.fn_call_expr.params.length; i += 1) {635 for (size_t i = 0; i < node->data.fn_call_expr.params.length; i += 1) {
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+90-31
...@@ -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,55 +4048,110 @@ static AstNode *parse_ctok(Context *c, CTokenize *ctok, size_t *tok_i) {...@@ -4044,55 +4048,110 @@ 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) {
4065 *tok_i += 1;
4066 return inner_node;
4067 }
4068
4069 AstNode *node_to_cast = parse_ctok_expr(c, ctok, tok_i);
4070 if (node_to_cast == nullptr) {
4071 return nullptr;
4072 }
4073
4074 CTok *next_tok2 = &ctok->tokens.at(*tok_i);
4075 if (next_tok2->id != CTokIdRParen) {
4082 return nullptr;4076 return nullptr;
4083 }4077 }
4084 *tok_i += 1;4078 *tok_i += 1;
4085 return inner_node;4079
4080 if (inner_node->type == NodeTypeAddrOfExpr) {
4081 AstNode *call_node = trans_create_node_builtin_fn_call_str(c, "ptrCast");
4082 call_node->data.fn_call_expr.params.append(inner_node);
4083 call_node->data.fn_call_expr.params.append(node_to_cast);
4084 return call_node;
4085 } else {
4086 return trans_create_node_cast(c, inner_node, node_to_cast);
4087 }
4086 }4088 }
4087 case CTokIdDot:4089 case CTokIdDot:
4088 case CTokIdEOF:4090 case CTokIdEOF:
4089 case CTokIdRParen:4091 case CTokIdRParen:
4092 case CTokIdAsterisk:
4093 case CTokIdBang:
4094 case CTokIdTilde:
4090 // not able to make sense of this4095 // not able to make sense of this
4091 return nullptr;4096 return nullptr;
4092 }4097 }
4093 zig_unreachable();4098 zig_unreachable();
4094}4099}
40954100
4101static AstNode *parse_ctok_expr(Context *c, CTokenize *ctok, size_t *tok_i) {
4102 return parse_ctok_prefix_op_expr(c, ctok, tok_i);
4103}
4104
4105static AstNode *parse_ctok_suffix_op_expr(Context *c, CTokenize *ctok, size_t *tok_i) {
4106 AstNode *node = parse_ctok_primary_expr(c, ctok, tok_i);
4107 if (node == nullptr)
4108 return nullptr;
4109
4110 while (true) {
4111 CTok *first_tok = &ctok->tokens.at(*tok_i);
4112 if (first_tok->id == CTokIdDot) {
4113 *tok_i += 1;
4114
4115 CTok *name_tok = &ctok->tokens.at(*tok_i);
4116 if (name_tok->id != CTokIdSymbol) {
4117 return nullptr;
4118 }
4119 *tok_i += 1;
4120
4121 node = trans_create_node_field_access(c, node, buf_create_from_buf(&name_tok->data.symbol));
4122 } else if (first_tok->id == CTokIdAsterisk) {
4123 *tok_i += 1;
4124
4125 node = trans_create_node_addr_of(c, false, false, node);
4126 } else {
4127 return node;
4128 }
4129 }
4130}
4131
4132static PrefixOp ctok_to_prefix_op(CTok *token) {
4133 switch (token->id) {
4134 case CTokIdBang: return PrefixOpBoolNot;
4135 case CTokIdMinus: return PrefixOpNegation;
4136 case CTokIdTilde: return PrefixOpBinNot;
4137 case CTokIdAsterisk: return PrefixOpDereference;
4138 default: return PrefixOpInvalid;
4139 }
4140}
4141static AstNode *parse_ctok_prefix_op_expr(Context *c, CTokenize *ctok, size_t *tok_i) {
4142 CTok *op_tok = &ctok->tokens.at(*tok_i);
4143 PrefixOp prefix_op = ctok_to_prefix_op(op_tok);
4144 if (prefix_op == PrefixOpInvalid) {
4145 return parse_ctok_suffix_op_expr(c, ctok, tok_i);
4146 }
4147 *tok_i += 1;
4148
4149 AstNode *prefix_op_expr = parse_ctok_prefix_op_expr(c, ctok, tok_i);
4150 if (prefix_op_expr == nullptr)
4151 return nullptr;
4152 return trans_create_node_prefix_op(c, prefix_op, prefix_op_expr);
4153}
4154
4096static void process_macro(Context *c, CTokenize *ctok, Buf *name, const char *char_ptr) {4155static void process_macro(Context *c, CTokenize *ctok, Buf *name, const char *char_ptr) {
4097 tokenize_c_macro(ctok, (const uint8_t *)char_ptr);4156 tokenize_c_macro(ctok, (const uint8_t *)char_ptr);
40984157
...@@ -4105,7 +4164,7 @@ static void process_macro(Context *c, CTokenize *ctok, Buf *name, const char *ch...@@ -4105,7 +4164,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));4164 assert(name_tok->id == CTokIdSymbol && buf_eql_buf(&name_tok->data.symbol, name));
4106 tok_i += 1;4165 tok_i += 1;
41074166
4108 AstNode *result_node = parse_ctok(c, ctok, &tok_i);4167 AstNode *result_node = parse_ctok_suffix_op_expr(c, ctok, &tok_i);
4109 if (result_node == nullptr) {4168 if (result_node == nullptr) {
4110 return;4169 return;
4111 }4170 }
test/translate_c.zig+8-2
...@@ -902,7 +902,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {...@@ -902,7 +902,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
902 \\}902 \\}
903 ,903 ,
904 \\export fn foo(x: ?&c_int) {904 \\export fn foo(x: ?&c_int) {
905 \\ (*(??x)) = 1;905 \\ (*??x) = 1;
906 \\}906 \\}
907 );907 );
908908
...@@ -930,7 +930,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {...@@ -930,7 +930,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
930 \\pub fn foo() -> c_int {930 \\pub fn foo() -> c_int {
931 \\ var x: c_int = 1234;931 \\ var x: c_int = 1234;
932 \\ var ptr: ?&c_int = &x;932 \\ var ptr: ?&c_int = &x;
933 \\ return *(??ptr);933 \\ return *??ptr;
934 \\}934 \\}
935 );935 );
936936
...@@ -1188,4 +1188,10 @@ pub fn addCases(cases: &tests.TranslateCContext) {...@@ -1188,4 +1188,10 @@ pub fn addCases(cases: &tests.TranslateCContext) {
1188 \\ const v2: &const u8 = c"2.2.2";1188 \\ const v2: &const u8 = c"2.2.2";
1189 \\}1189 \\}
1190 );1190 );
1191
1192 cases.add("macro pointer cast",
1193 \\#define NRF_GPIO ((NRF_GPIO_Type *) NRF_GPIO_BASE)
1194 ,
1195 \\pub const NRF_GPIO = @ptrCast(&NRF_GPIO_Type, NRF_GPIO_BASE);
1196 );
1191}1197}