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) {
584584 PrefixOp op = node->data.prefix_op_expr.prefix_op;
585585 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);
588590 if (!grouped) fprintf(ar->f, ")");
589591 break;
590592 }
591593 case NodeTypeAddrOfExpr:
592594 {
595 if (!grouped) fprintf(ar->f, "(");
593596 fprintf(ar->f, "&");
594597 if (node->data.addr_of_expr.align_expr != nullptr) {
595598 fprintf(ar->f, "align(");
......@@ -617,6 +620,7 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {
617620 }
618621
619622 render_node_ungrouped(ar, node->data.addr_of_expr.op_expr);
623 if (!grouped) fprintf(ar->f, ")");
620624 break;
621625 }
622626 case NodeTypeFnCallExpr:
......@@ -625,7 +629,7 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {
625629 fprintf(ar->f, "@");
626630 }
627631 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);
629633 render_node_extra(ar, fn_ref_node, grouped);
630634 fprintf(ar->f, "(");
631635 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) {
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+90-31
......@@ -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,55 +4048,110 @@ 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);
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) {
40824076 return nullptr;
40834077 }
40844078 *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 }
40864088 }
40874089 case CTokIdDot:
40884090 case CTokIdEOF:
40894091 case CTokIdRParen:
4092 case CTokIdAsterisk:
4093 case CTokIdBang:
4094 case CTokIdTilde:
40904095 // not able to make sense of this
40914096 return nullptr;
40924097 }
40934098 zig_unreachable();
40944099}
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
40964155static void process_macro(Context *c, CTokenize *ctok, Buf *name, const char *char_ptr) {
40974156 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
41054164 assert(name_tok->id == CTokIdSymbol && buf_eql_buf(&name_tok->data.symbol, name));
41064165 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);
41094168 if (result_node == nullptr) {
41104169 return;
41114170 }
test/translate_c.zig+8-2
......@@ -902,7 +902,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
902902 \\}
903903 ,
904904 \\export fn foo(x: ?&c_int) {
905 \\ (*(??x)) = 1;
905 \\ (*??x) = 1;
906906 \\}
907907 );
908908
......@@ -930,7 +930,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
930930 \\pub fn foo() -> c_int {
931931 \\ var x: c_int = 1234;
932932 \\ var ptr: ?&c_int = &x;
933 \\ return *(??ptr);
933 \\ return *??ptr;
934934 \\}
935935 );
936936
......@@ -1188,4 +1188,10 @@ pub fn addCases(cases: &tests.TranslateCContext) {
11881188 \\ const v2: &const u8 = c"2.2.2";
11891189 \\}
11901190 );
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 );
11911197}