| ... | ... | @@ -2261,9 +2261,37 @@ fn transCreatePreCrement( |
| 2261 | 2261 | // c: ++expr |
| 2262 | 2262 | // zig: (blk: { |
| 2263 | 2263 | // zig: const _ref = &expr; |
| 2264 | | // zig: *_ref += 1; |
| 2265 | | // zig: break :blk *_ref |
| 2264 | // zig: _ref.* += 1; |
| 2265 | // zig: break :blk _ref.* |
| 2266 | 2266 | // zig: }) |
| 2267 | const block_scope = try Scope.Block.init(rp.c, scope, "blk"); |
| 2268 | block_scope.block_node = try transCreateNodeBlock(rp.c, block_scope.label); |
| 2269 | const ref = try std.fmt.allocPrint(rp.c.a(), "_ref_{}", .{rp.c.getMangle()}); |
| 2270 | |
| 2271 | const node = try transCreateNodeVarDecl(rp.c, false, true, ref); |
| 2272 | node.eq_token = try appendToken(rp.c, .Equal, "="); |
| 2273 | const rhs_node = try transCreateNodePrefixOp(rp.c, .AddressOf, .Ampersand, "&"); |
| 2274 | rhs_node.rhs = try transExpr(rp, scope, op_expr, .used, .r_value); |
| 2275 | node.init_node = &rhs_node.base; |
| 2276 | node.semicolon_token = try appendToken(rp.c, .Semicolon, ";"); |
| 2277 | try block_scope.block_node.statements.push(&node.base); |
| 2278 | |
| 2279 | const lhs_node = try transCreateNodeIdentifier(rp.c, ref); |
| 2280 | const ref_node = try transCreateNodePtrDeref(rp.c, lhs_node); |
| 2281 | _ = try appendToken(rp.c, .Semicolon, ";"); |
| 2282 | const token = try appendToken(rp.c, op_tok_id, bytes); |
| 2283 | const one = try transCreateNodeInt(rp.c, 1); |
| 2284 | _ = try appendToken(rp.c, .Semicolon, ";"); |
| 2285 | const assign = try transCreateNodeInfixOp(rp, scope, ref_node, op, token, one, .used, false); |
| 2286 | try block_scope.block_node.statements.push(assign); |
| 2287 | |
| 2288 | const break_node = try transCreateNodeBreak(rp.c, block_scope.label); |
| 2289 | break_node.rhs = ref_node; |
| 2290 | try block_scope.block_node.statements.push(&break_node.base); |
| 2291 | block_scope.block_node.rbrace = try appendToken(rp.c, .RBrace, "}"); |
| 2292 | // semicolon must immediately follow rbrace because it is the last token in a block |
| 2293 | _ = try appendToken(rp.c, .Semicolon, ";"); |
| 2294 | return &block_scope.block_node.base; |
| 2267 | 2295 | } |
| 2268 | 2296 | |
| 2269 | 2297 | fn transCreatePostCrement( |
| ... | ... | @@ -2291,10 +2319,45 @@ fn transCreatePostCrement( |
| 2291 | 2319 | // c: expr++ |
| 2292 | 2320 | // zig: (blk: { |
| 2293 | 2321 | // zig: const _ref = &expr; |
| 2294 | | // zig: const _tmp = *_ref; |
| 2295 | | // zig: *_ref += 1; |
| 2322 | // zig: const _tmp = _ref.*; |
| 2323 | // zig: _ref.* += 1; |
| 2296 | 2324 | // zig: break :blk _tmp |
| 2297 | 2325 | // zig: }) |
| 2326 | const block_scope = try Scope.Block.init(rp.c, scope, "blk"); |
| 2327 | block_scope.block_node = try transCreateNodeBlock(rp.c, block_scope.label); |
| 2328 | const ref = try std.fmt.allocPrint(rp.c.a(), "_ref_{}", .{rp.c.getMangle()}); |
| 2329 | |
| 2330 | const node = try transCreateNodeVarDecl(rp.c, false, true, ref); |
| 2331 | node.eq_token = try appendToken(rp.c, .Equal, "="); |
| 2332 | const rhs_node = try transCreateNodePrefixOp(rp.c, .AddressOf, .Ampersand, "&"); |
| 2333 | rhs_node.rhs = try transExpr(rp, scope, op_expr, .used, .r_value); |
| 2334 | node.init_node = &rhs_node.base; |
| 2335 | node.semicolon_token = try appendToken(rp.c, .Semicolon, ";"); |
| 2336 | try block_scope.block_node.statements.push(&node.base); |
| 2337 | |
| 2338 | const lhs_node = try transCreateNodeIdentifier(rp.c, ref); |
| 2339 | const ref_node = try transCreateNodePtrDeref(rp.c, lhs_node); |
| 2340 | _ = try appendToken(rp.c, .Semicolon, ";"); |
| 2341 | |
| 2342 | const tmp = try std.fmt.allocPrint(rp.c.a(), "_tmp_{}", .{rp.c.getMangle()}); |
| 2343 | const tmp_node = try transCreateNodeVarDecl(rp.c, false, true, tmp); |
| 2344 | tmp_node.eq_token = try appendToken(rp.c, .Equal, "="); |
| 2345 | tmp_node.init_node = ref_node; |
| 2346 | tmp_node.semicolon_token = try appendToken(rp.c, .Semicolon, ";"); |
| 2347 | try block_scope.block_node.statements.push(&tmp_node.base); |
| 2348 | |
| 2349 | const token = try appendToken(rp.c, op_tok_id, bytes); |
| 2350 | const one = try transCreateNodeInt(rp.c, 1); |
| 2351 | _ = try appendToken(rp.c, .Semicolon, ";"); |
| 2352 | const assign = try transCreateNodeInfixOp(rp, scope, ref_node, op, token, one, .used, false); |
| 2353 | try block_scope.block_node.statements.push(assign); |
| 2354 | |
| 2355 | const break_node = try transCreateNodeBreak(rp.c, block_scope.label); |
| 2356 | break_node.rhs = try transCreateNodeIdentifier(rp.c,tmp); |
| 2357 | try block_scope.block_node.statements.push(&break_node.base); |
| 2358 | _ = try appendToken(rp.c, .Semicolon, ";"); |
| 2359 | block_scope.block_node.rbrace = try appendToken(rp.c, .RBrace, "}"); |
| 2360 | return &block_scope.block_node.base; |
| 2298 | 2361 | } |
| 2299 | 2362 | |
| 2300 | 2363 | fn transCPtrCast( |
| ... | ... | @@ -2694,25 +2757,16 @@ fn transCreateNodeAssign( |
| 2694 | 2757 | } |
| 2695 | 2758 | if (scope.id != .Condition) |
| 2696 | 2759 | _ = try appendToken(rp.c, .Semicolon, ";"); |
| 2697 | | |
| 2698 | | const node = try rp.c.a().create(ast.Node.InfixOp); |
| 2699 | | node.* = .{ |
| 2700 | | .op_token = eq_token, |
| 2701 | | .lhs = lhs_node, |
| 2702 | | .op = .Assign, |
| 2703 | | .rhs = rhs_node, |
| 2704 | | }; |
| 2705 | | return &node.base; |
| 2760 | return transCreateNodeInfixOp(rp, scope, lhs_node, .Assign, eq_token, rhs_node, .used, false); |
| 2706 | 2761 | } |
| 2707 | 2762 | |
| 2708 | 2763 | // worst case |
| 2709 | 2764 | // c: lhs = rhs |
| 2710 | | // zig: (x: { |
| 2765 | // zig: (blk: { |
| 2711 | 2766 | // zig: const _tmp = rhs; |
| 2712 | 2767 | // zig: lhs = _tmp; |
| 2713 | | // zig: break :x _tmp |
| 2768 | // zig: break :blk _tmp |
| 2714 | 2769 | // zig: }) |
| 2715 | | _ = try appendToken(rp.c, .LParen, "("); |
| 2716 | 2770 | const block_scope = try Scope.Block.init(rp.c, scope, "blk"); |
| 2717 | 2771 | block_scope.block_node = try transCreateNodeBlock(rp.c, block_scope.label); |
| 2718 | 2772 | const tmp = try std.fmt.allocPrint(rp.c.a(), "_tmp_{}", .{rp.c.getMangle()}); |
| ... | ... | @@ -2735,14 +2789,8 @@ fn transCreateNodeAssign( |
| 2735 | 2789 | const ident = try transCreateNodeIdentifier(rp.c, tmp); |
| 2736 | 2790 | _ = try appendToken(rp.c, .Semicolon, ";"); |
| 2737 | 2791 | |
| 2738 | | const assign = try rp.c.a().create(ast.Node.InfixOp); |
| 2739 | | assign.* = .{ |
| 2740 | | .op_token = eq_token, |
| 2741 | | .lhs = lhs_node, |
| 2742 | | .op = .Assign, |
| 2743 | | .rhs = ident, |
| 2744 | | }; |
| 2745 | | try block_scope.block_node.statements.push(&assign.base); |
| 2792 | const assign = try transCreateNodeInfixOp(rp, scope, lhs_node, .Assign, eq_token, ident, .used, false); |
| 2793 | try block_scope.block_node.statements.push(assign); |
| 2746 | 2794 | |
| 2747 | 2795 | const break_node = try transCreateNodeBreak(rp.c, block_scope.label); |
| 2748 | 2796 | break_node.rhs = try transCreateNodeIdentifier(rp.c, tmp); |
| ... | ... | @@ -2751,7 +2799,6 @@ fn transCreateNodeAssign( |
| 2751 | 2799 | block_scope.block_node.rbrace = try appendToken(rp.c, .RBrace, "}"); |
| 2752 | 2800 | // semicolon must immediately follow rbrace because it is the last token in a block |
| 2753 | 2801 | _ = try appendToken(rp.c, .Semicolon, ";"); |
| 2754 | | _ = try appendToken(rp.c, .RParen, ")"); |
| 2755 | 2802 | return &block_scope.block_node.base; |
| 2756 | 2803 | } |
| 2757 | 2804 | |