Merge pull request #4636 from Vexu/translate-c

Translate-c macro comma operator
This commit is contained in:
Andrew Kelley 2020-03-05 10:38:51 -05:00 committed by GitHub
commit b7614e63f5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 73 additions and 2 deletions

View File

@ -4874,7 +4874,7 @@ fn transPreprocessorEntities(c: *Context, unit: *ZigClangASTUnit) Error!void {
var tok_it = tok_list.iterator(0);
const first_tok = tok_it.next().?;
assert(first_tok.id == .Identifier and mem.eql(u8, slice[first_tok.start..first_tok.end], name));
assert(mem.eql(u8, slice[first_tok.start..first_tok.end], name));
var macro_fn = false;
const next = tok_it.peek().?;
@ -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;

View File

@ -3,6 +3,37 @@ 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 keyword define",
\\#define foo 1
\\#define inline 2
, &[_][]const u8{
\\pub const foo = 1;
,
\\pub const @"inline" = 2;
});
cases.add("macro line continuation",
\\#define FOO -\
\\BAR