Commit 182cf5b8de

Andrew Kelley <superjoe30@gmail.com>
2017-12-07 18:27:29
translate-c: support macros with pointer casting
1 parent dc50204
src/ast_render.cpp
@@ -584,12 +584,15 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {
                 PrefixOp op = node->data.prefix_op_expr.prefix_op;
                 fprintf(ar->f, "%s", prefix_op_str(op));
 
-                render_node_ungrouped(ar, node->data.prefix_op_expr.primary_expr);
+                AstNode *child_node = node->data.prefix_op_expr.primary_expr;
+                bool new_grouped = child_node->type == NodeTypePrefixOpExpr || child_node->type == NodeTypeAddrOfExpr;
+                render_node_extra(ar, child_node, new_grouped);
                 if (!grouped) fprintf(ar->f, ")");
                 break;
             }
         case NodeTypeAddrOfExpr:
             {
+                if (!grouped) fprintf(ar->f, "(");
                 fprintf(ar->f, "&");
                 if (node->data.addr_of_expr.align_expr != nullptr) {
                     fprintf(ar->f, "align(");
@@ -617,6 +620,7 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {
                 }
 
                 render_node_ungrouped(ar, node->data.addr_of_expr.op_expr);
+                if (!grouped) fprintf(ar->f, ")");
                 break;
             }
         case NodeTypeFnCallExpr:
@@ -625,7 +629,7 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {
                     fprintf(ar->f, "@");
                 }
                 AstNode *fn_ref_node = node->data.fn_call_expr.fn_ref_expr;
-                bool grouped = (fn_ref_node->type != NodeTypePrefixOpExpr);
+                bool grouped = (fn_ref_node->type != NodeTypePrefixOpExpr && fn_ref_node->type != NodeTypeAddrOfExpr);
                 render_node_extra(ar, fn_ref_node, grouped);
                 fprintf(ar->f, "(");
                 for (size_t i = 0; i < node->data.fn_call_expr.params.length; i += 1) {
src/translate_c.cpp
@@ -4061,11 +4061,30 @@ static AstNode *parse_ctok_primary_expr(Context *c, CTokenize *ctok, size_t *tok
                 }
 
                 CTok *next_tok = &ctok->tokens.at(*tok_i);
-                if (next_tok->id != CTokIdRParen) {
+                if (next_tok->id == CTokIdRParen) {
+                    *tok_i += 1;
+                    return inner_node;
+                }
+
+                AstNode *node_to_cast = parse_ctok_expr(c, ctok, tok_i);
+                if (node_to_cast == nullptr) {
+                    return nullptr;
+                }
+
+                CTok *next_tok2 = &ctok->tokens.at(*tok_i);
+                if (next_tok2->id != CTokIdRParen) {
                     return nullptr;
                 }
                 *tok_i += 1;
-                return inner_node;
+
+                if (inner_node->type == NodeTypeAddrOfExpr) {
+                    AstNode *call_node = trans_create_node_builtin_fn_call_str(c, "ptrCast");
+                    call_node->data.fn_call_expr.params.append(inner_node);
+                    call_node->data.fn_call_expr.params.append(node_to_cast);
+                    return call_node;
+                } else {
+                    return trans_create_node_cast(c, inner_node, node_to_cast);
+                }
             }
         case CTokIdDot:
         case CTokIdEOF:
test/translate_c.zig
@@ -902,7 +902,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
         \\}
     ,
         \\export fn foo(x: ?&c_int) {
-        \\    (*(??x)) = 1;
+        \\    (*??x) = 1;
         \\}
     );
 
@@ -930,7 +930,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
         \\pub fn foo() -> c_int {
         \\    var x: c_int = 1234;
         \\    var ptr: ?&c_int = &x;
-        \\    return *(??ptr);
+        \\    return *??ptr;
         \\}
     );
 
@@ -1188,4 +1188,10 @@ pub fn addCases(cases: &tests.TranslateCContext) {
         \\    const v2: &const u8 = c"2.2.2";
         \\}
     );
+
+    cases.add("macro pointer cast",
+        \\#define NRF_GPIO ((NRF_GPIO_Type *) NRF_GPIO_BASE) 
+    ,
+        \\pub const NRF_GPIO = @ptrCast(&NRF_GPIO_Type, NRF_GPIO_BASE);
+    );
 }