authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2020-03-05 11:22:50+02:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2020-03-05 11:22:50+02:00
log8088bdc6d5d751766b4b4df700b864b5a0397eb6
tree2b234b784357879a80beab7f56003fabd3ee01ae
parent378bf1c3b71fdcc823fb9a5382400ec0a659fc00
signaturelock-open Commit is signed but in an unrecognized format.

translate-c macro comma operator


2 files changed, 63 insertions(+), 1 deletions(-)

src-self-hosted/translate_c.zig+41-1
...@@ -5038,7 +5038,14 @@ fn transMacroFnDefine(c: *Context, it: *CTokenList.Iterator, source: []const u8,...@@ -5038,7 +5038,14 @@ fn transMacroFnDefine(c: *Context, it: *CTokenList.Iterator, source: []const u8,
5038 .{last.id},5038 .{last.id},
5039 );5039 );
5040 _ = try appendToken(c, .Semicolon, ";");5040 _ = try appendToken(c, .Semicolon, ";");
5041 try type_of.params.push(expr);5041 const type_of_arg = if (expr.id != .Block) expr else blk: {
5042 const blk = @fieldParentPtr(ast.Node.Block, "base", expr);
5043 const blk_last = blk.statements.at(blk.statements.len - 1).*;
5044 std.debug.assert(blk_last.id == .ControlFlowExpression);
5045 const br = @fieldParentPtr(ast.Node.ControlFlowExpression, "base", blk_last);
5046 break :blk br.rhs.?;
5047 };
5048 try type_of.params.push(type_of_arg);
5042 return_expr.rhs = expr;5049 return_expr.rhs = expr;
50435050
5044 block.rbrace = try appendToken(c, .RBrace, "}");5051 block.rbrace = try appendToken(c, .RBrace, "}");
...@@ -5073,6 +5080,39 @@ fn parseCExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8, source_...@@ -5073,6 +5080,39 @@ fn parseCExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8, source_
5073 if_node.@"else".?.body = try parseCPrimaryExpr(c, it, source, source_loc, scope);5080 if_node.@"else".?.body = try parseCPrimaryExpr(c, it, source, source_loc, scope);
5074 return &if_node.base;5081 return &if_node.base;
5075 },5082 },
5083 .Comma => {
5084 _ = try appendToken(c, .Semicolon, ";");
5085 const block_scope = try Scope.Block.init(c, scope, "blk");
5086 block_scope.block_node = try transCreateNodeBlock(c, block_scope.label);
5087
5088 var last = node;
5089 while (true) {
5090 // suppress result
5091 const lhs = try transCreateNodeIdentifier(c, "_");
5092 const op_token = try appendToken(c, .Equal, "=");
5093 const op_node = try c.a().create(ast.Node.InfixOp);
5094 op_node.* = .{
5095 .op_token = op_token,
5096 .lhs = lhs,
5097 .op = .Assign,
5098 .rhs = last,
5099 };
5100 try block_scope.block_node.statements.push(&op_node.base);
5101
5102 last = try parseCPrefixOpExpr(c, it, source, source_loc, scope);
5103 _ = try appendToken(c, .Semicolon, ";");
5104 if (it.next().?.id != .Comma) {
5105 _ = it.prev();
5106 break;
5107 }
5108 }
5109
5110 const break_node = try transCreateNodeBreak(c, block_scope.label);
5111 break_node.rhs = last;
5112 try block_scope.block_node.statements.push(&break_node.base);
5113 block_scope.block_node.rbrace = try appendToken(c, .RBrace, "}");
5114 return &block_scope.block_node.base;
5115 },
5076 else => {5116 else => {
5077 _ = it.prev();5117 _ = it.prev();
5078 return node;5118 return node;
test/translate_c.zig+22
...@@ -3,6 +3,28 @@ const std = @import("std");...@@ -3,6 +3,28 @@ const std = @import("std");
3const CrossTarget = std.zig.CrossTarget;3const CrossTarget = std.zig.CrossTarget;
44
5pub fn addCases(cases: *tests.TranslateCContext) void {5pub fn addCases(cases: *tests.TranslateCContext) void {
6 cases.add("macro comma operator",
7 \\#define foo (foo, bar)
8 \\#define bar(x) (x, 3, 4, 5 * 6, baz(1, 2), 2, baz(1,2))
9 , &[_][]const u8{
10 \\pub const foo = blk: {
11 \\ _ = foo;
12 \\ break :blk bar;
13 \\};
14 ,
15 \\pub inline fn bar(x: var) @TypeOf(baz(1, 2)) {
16 \\ return blk: {
17 \\ _ = x;
18 \\ _ = 3;
19 \\ _ = 4;
20 \\ _ = 5 * 6;
21 \\ _ = baz(1, 2);
22 \\ _ = 2;
23 \\ break :blk baz(1, 2);
24 \\ };
25 \\}
26 });
27
6 cases.add("macro line continuation",28 cases.add("macro line continuation",
7 \\#define FOO -\29 \\#define FOO -\
8 \\BAR30 \\BAR