Commit 8088bdc6d5
Changed files (2)
src-self-hosted
test
src-self-hosted/translate_c.zig
@@ -5038,7 +5038,14 @@ fn transMacroFnDefine(c: *Context, it: *CTokenList.Iterator, source: []const u8,
.{last.id},
);
_ = try appendToken(c, .Semicolon, ";");
- try type_of.params.push(expr);
+ const type_of_arg = if (expr.id != .Block) expr else blk: {
+ const blk = @fieldParentPtr(ast.Node.Block, "base", expr);
+ const blk_last = blk.statements.at(blk.statements.len - 1).*;
+ std.debug.assert(blk_last.id == .ControlFlowExpression);
+ const br = @fieldParentPtr(ast.Node.ControlFlowExpression, "base", blk_last);
+ break :blk br.rhs.?;
+ };
+ try type_of.params.push(type_of_arg);
return_expr.rhs = expr;
block.rbrace = try appendToken(c, .RBrace, "}");
@@ -5073,6 +5080,39 @@ fn parseCExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8, source_
if_node.@"else".?.body = try parseCPrimaryExpr(c, it, source, source_loc, scope);
return &if_node.base;
},
+ .Comma => {
+ _ = try appendToken(c, .Semicolon, ";");
+ const block_scope = try Scope.Block.init(c, scope, "blk");
+ block_scope.block_node = try transCreateNodeBlock(c, block_scope.label);
+
+ var last = node;
+ while (true) {
+ // suppress result
+ const lhs = try transCreateNodeIdentifier(c, "_");
+ const op_token = try appendToken(c, .Equal, "=");
+ const op_node = try c.a().create(ast.Node.InfixOp);
+ op_node.* = .{
+ .op_token = op_token,
+ .lhs = lhs,
+ .op = .Assign,
+ .rhs = last,
+ };
+ try block_scope.block_node.statements.push(&op_node.base);
+
+ last = try parseCPrefixOpExpr(c, it, source, source_loc, scope);
+ _ = try appendToken(c, .Semicolon, ";");
+ if (it.next().?.id != .Comma) {
+ _ = it.prev();
+ break;
+ }
+ }
+
+ const break_node = try transCreateNodeBreak(c, block_scope.label);
+ break_node.rhs = last;
+ try block_scope.block_node.statements.push(&break_node.base);
+ block_scope.block_node.rbrace = try appendToken(c, .RBrace, "}");
+ return &block_scope.block_node.base;
+ },
else => {
_ = it.prev();
return node;
test/translate_c.zig
@@ -3,6 +3,28 @@ const std = @import("std");
const CrossTarget = std.zig.CrossTarget;
pub fn addCases(cases: *tests.TranslateCContext) void {
+ cases.add("macro comma operator",
+ \\#define foo (foo, bar)
+ \\#define bar(x) (x, 3, 4, 5 * 6, baz(1, 2), 2, baz(1,2))
+ , &[_][]const u8{
+ \\pub const foo = blk: {
+ \\ _ = foo;
+ \\ break :blk bar;
+ \\};
+ ,
+ \\pub inline fn bar(x: var) @TypeOf(baz(1, 2)) {
+ \\ return blk: {
+ \\ _ = x;
+ \\ _ = 3;
+ \\ _ = 4;
+ \\ _ = 5 * 6;
+ \\ _ = baz(1, 2);
+ \\ _ = 2;
+ \\ break :blk baz(1, 2);
+ \\ };
+ \\}
+ });
+
cases.add("macro line continuation",
\\#define FOO -\
\\BAR