translate-c: support initializer list expr macros
This commit is contained in:
@@ -6061,6 +6061,61 @@ fn parseCSuffixOpExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8,
|
||||
node = &call_node.base;
|
||||
continue;
|
||||
},
|
||||
.LBrace => {
|
||||
// must come immediately after `node`
|
||||
_ = try appendToken(c, .Comma, ",");
|
||||
|
||||
const dot = try appendToken(c, .Period, ".");
|
||||
_ = try appendToken(c, .LBrace, "{");
|
||||
|
||||
var init_vals = std.ArrayList(*ast.Node).init(c.gpa);
|
||||
defer init_vals.deinit();
|
||||
|
||||
while (true) {
|
||||
const val = try parseCPrefixOpExpr(c, it, source, source_loc, scope);
|
||||
try init_vals.append(val);
|
||||
const next = it.next().?;
|
||||
if (next.id == .Comma)
|
||||
_ = try appendToken(c, .Comma, ",")
|
||||
else if (next.id == .RBrace)
|
||||
break
|
||||
else {
|
||||
const first_tok = it.list.at(0);
|
||||
try failDecl(
|
||||
c,
|
||||
source_loc,
|
||||
source[first_tok.start..first_tok.end],
|
||||
"unable to translate C expr: expected ',' or '}}'",
|
||||
.{},
|
||||
);
|
||||
return error.ParseError;
|
||||
}
|
||||
}
|
||||
const tuple_node = try ast.Node.StructInitializerDot.alloc(c.arena, init_vals.items.len);
|
||||
tuple_node.* = .{
|
||||
.dot = dot,
|
||||
.list_len = init_vals.items.len,
|
||||
.rtoken = try appendToken(c, .RBrace, "}"),
|
||||
};
|
||||
mem.copy(*ast.Node, tuple_node.list(), init_vals.items);
|
||||
|
||||
|
||||
//(@import("std").mem.zeroInit(T, .{x}))
|
||||
const import_fn_call = try c.createBuiltinCall("@import", 1);
|
||||
const std_node = try transCreateNodeStringLiteral(c, "\"std\"");
|
||||
import_fn_call.params()[0] = std_node;
|
||||
import_fn_call.rparen_token = try appendToken(c, .RParen, ")");
|
||||
const inner_field_access = try transCreateNodeFieldAccess(c, &import_fn_call.base, "mem");
|
||||
const outer_field_access = try transCreateNodeFieldAccess(c, inner_field_access, "zeroInit");
|
||||
|
||||
const zero_init_call = try c.createCall(outer_field_access, 2);
|
||||
zero_init_call.params()[0] = node;
|
||||
zero_init_call.params()[1] = &tuple_node.base;
|
||||
zero_init_call.rtoken = try appendToken(c, .RParen, ")");
|
||||
|
||||
node = &zero_init_call.base;
|
||||
continue;
|
||||
},
|
||||
.BangEqual => {
|
||||
op_token = try appendToken(c, .BangEqual, "!=");
|
||||
op_id = .BangEqual;
|
||||
|
||||
@@ -3,6 +3,31 @@ const std = @import("std");
|
||||
const CrossTarget = std.zig.CrossTarget;
|
||||
|
||||
pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
cases.add("initializer list macro",
|
||||
\\typedef struct Color {
|
||||
\\ unsigned char r;
|
||||
\\ unsigned char g;
|
||||
\\ unsigned char b;
|
||||
\\ unsigned char a;
|
||||
\\} Color;
|
||||
\\#define CLITERAL(type) (type)
|
||||
\\#define LIGHTGRAY CLITERAL(Color){ 200, 200, 200, 255 } // Light Gray
|
||||
, &[_][]const u8{ // TODO properly translate this
|
||||
\\pub const struct_Color = extern struct {
|
||||
\\ r: u8,
|
||||
\\ g: u8,
|
||||
\\ b: u8,
|
||||
\\ a: u8,
|
||||
\\};
|
||||
\\pub const Color = struct_Color;
|
||||
,
|
||||
\\pub inline fn CLITERAL(type_1: anytype) @TypeOf(type_1) {
|
||||
\\ return type_1;
|
||||
\\}
|
||||
,
|
||||
\\pub const LIGHTGRAY = @import("std").mem.zeroInit(CLITERAL(Color), .{ 200, 200, 200, 255 });
|
||||
});
|
||||
|
||||
cases.add("complex switch",
|
||||
\\int main() {
|
||||
\\ int i = 2;
|
||||
|
||||
Reference in New Issue
Block a user