authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2020-07-16 16:20:47+03:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2020-07-16 16:20:47+03:00
log37647375dcb817f88895ba1a17d648184727e4cc
treeb3705a49ff317a72bf3fd4d6385d592a93d3b4ea
parent8fe076daaf182863d116f2be7b13e3743bbcaae3
signaturelock-open Commit is signed but in an unrecognized format.

translate-c: support initializer list expr macros


2 files changed, 80 insertions(+), 0 deletions(-)

src-self-hosted/translate_c.zig+55
......@@ -6061,6 +6061,61 @@ fn parseCSuffixOpExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8,
60616061 node = &call_node.base;
60626062 continue;
60636063 },
6064 .LBrace => {
6065 // must come immediately after `node`
6066 _ = try appendToken(c, .Comma, ",");
6067
6068 const dot = try appendToken(c, .Period, ".");
6069 _ = try appendToken(c, .LBrace, "{");
6070
6071 var init_vals = std.ArrayList(*ast.Node).init(c.gpa);
6072 defer init_vals.deinit();
6073
6074 while (true) {
6075 const val = try parseCPrefixOpExpr(c, it, source, source_loc, scope);
6076 try init_vals.append(val);
6077 const next = it.next().?;
6078 if (next.id == .Comma)
6079 _ = try appendToken(c, .Comma, ",")
6080 else if (next.id == .RBrace)
6081 break
6082 else {
6083 const first_tok = it.list.at(0);
6084 try failDecl(
6085 c,
6086 source_loc,
6087 source[first_tok.start..first_tok.end],
6088 "unable to translate C expr: expected ',' or '}}'",
6089 .{},
6090 );
6091 return error.ParseError;
6092 }
6093 }
6094 const tuple_node = try ast.Node.StructInitializerDot.alloc(c.arena, init_vals.items.len);
6095 tuple_node.* = .{
6096 .dot = dot,
6097 .list_len = init_vals.items.len,
6098 .rtoken = try appendToken(c, .RBrace, "}"),
6099 };
6100 mem.copy(*ast.Node, tuple_node.list(), init_vals.items);
6101
6102
6103 //(@import("std").mem.zeroInit(T, .{x}))
6104 const import_fn_call = try c.createBuiltinCall("@import", 1);
6105 const std_node = try transCreateNodeStringLiteral(c, "\"std\"");
6106 import_fn_call.params()[0] = std_node;
6107 import_fn_call.rparen_token = try appendToken(c, .RParen, ")");
6108 const inner_field_access = try transCreateNodeFieldAccess(c, &import_fn_call.base, "mem");
6109 const outer_field_access = try transCreateNodeFieldAccess(c, inner_field_access, "zeroInit");
6110
6111 const zero_init_call = try c.createCall(outer_field_access, 2);
6112 zero_init_call.params()[0] = node;
6113 zero_init_call.params()[1] = &tuple_node.base;
6114 zero_init_call.rtoken = try appendToken(c, .RParen, ")");
6115
6116 node = &zero_init_call.base;
6117 continue;
6118 },
60646119 .BangEqual => {
60656120 op_token = try appendToken(c, .BangEqual, "!=");
60666121 op_id = .BangEqual;
test/translate_c.zig+25
......@@ -3,6 +3,31 @@ const std = @import("std");
33const CrossTarget = std.zig.CrossTarget;
44
55pub fn addCases(cases: *tests.TranslateCContext) void {
6 cases.add("initializer list macro",
7 \\typedef struct Color {
8 \\ unsigned char r;
9 \\ unsigned char g;
10 \\ unsigned char b;
11 \\ unsigned char a;
12 \\} Color;
13 \\#define CLITERAL(type) (type)
14 \\#define LIGHTGRAY CLITERAL(Color){ 200, 200, 200, 255 } // Light Gray
15 , &[_][]const u8{ // TODO properly translate this
16 \\pub const struct_Color = extern struct {
17 \\ r: u8,
18 \\ g: u8,
19 \\ b: u8,
20 \\ a: u8,
21 \\};
22 \\pub const Color = struct_Color;
23 ,
24 \\pub inline fn CLITERAL(type_1: anytype) @TypeOf(type_1) {
25 \\ return type_1;
26 \\}
27 ,
28 \\pub const LIGHTGRAY = @import("std").mem.zeroInit(CLITERAL(Color), .{ 200, 200, 200, 255 });
29 });
30
631 cases.add("complex switch",
732 \\int main() {
833 \\ int i = 2;