| author | |
| committer | |
| log | c6a0a4e7282d746ebf2b54df16161c5993ea5aa8 |
| tree | 70fae1d044589b07a8835e000e2c7c4e77726102 |
| parent | 99b6305aa89c6363b1220a780485803a66880cce |
3 files changed, 112 insertions(+), 13 deletions(-)
src/translate_c.zig+45-4| ... | @@ -4813,8 +4813,11 @@ fn transMacroFnDefine(c: *Context, m: *MacroCtx) ParseError!void { | ... | @@ -4813,8 +4813,11 @@ fn transMacroFnDefine(c: *Context, m: *MacroCtx) ParseError!void { |
| 4813 | const br = blk_last.castTag(.break_val).?; | 4813 | const br = blk_last.castTag(.break_val).?; |
| 4814 | break :blk br.data.val; | 4814 | break :blk br.data.val; |
| 4815 | } else expr; | 4815 | } else expr; |
| 4816 | const return_type = if (typeof_arg.castTag(.std_meta_cast)) |some| | 4816 | |
| 4817 | const return_type = if (typeof_arg.castTag(.std_meta_cast) orelse typeof_arg.castTag(.std_mem_zeroinit)) |some| | ||
| 4817 | some.data.lhs | 4818 | some.data.lhs |
| 4819 | else if (typeof_arg.castTag(.std_mem_zeroes)) |some| | ||
| 4820 | some.data | ||
| 4818 | else | 4821 | else |
| 4819 | try Tag.typeof.create(c.arena, typeof_arg); | 4822 | try Tag.typeof.create(c.arena, typeof_arg); |
| 4820 | 4823 | ||
| ... | @@ -4932,6 +4935,7 @@ fn parseCNumLit(c: *Context, m: *MacroCtx) ParseError!Node { | ... | @@ -4932,6 +4935,7 @@ fn parseCNumLit(c: *Context, m: *MacroCtx) ParseError!Node { |
| 4932 | } | 4935 | } |
| 4933 | }, | 4936 | }, |
| 4934 | .FloatLiteral => |suffix| { | 4937 | .FloatLiteral => |suffix| { |
| 4938 | if (suffix != .none) lit_bytes = lit_bytes[0 .. lit_bytes.len - 1]; | ||
| 4935 | const dot_index = mem.indexOfScalar(u8, lit_bytes, '.').?; | 4939 | const dot_index = mem.indexOfScalar(u8, lit_bytes, '.').?; |
| 4936 | if (dot_index == 0) { | 4940 | if (dot_index == 0) { |
| 4937 | lit_bytes = try std.fmt.allocPrint(c.arena, "0{s}", .{lit_bytes}); | 4941 | lit_bytes = try std.fmt.allocPrint(c.arena, "0{s}", .{lit_bytes}); |
| ... | @@ -4943,15 +4947,16 @@ fn parseCNumLit(c: *Context, m: *MacroCtx) ParseError!Node { | ... | @@ -4943,15 +4947,16 @@ fn parseCNumLit(c: *Context, m: *MacroCtx) ParseError!Node { |
| 4943 | lit_bytes[dot_index + 1 ..], | 4947 | lit_bytes[dot_index + 1 ..], |
| 4944 | }); | 4948 | }); |
| 4945 | } | 4949 | } |
| 4946 | if (suffix == .none) { | 4950 | |
| 4951 | if (suffix == .none) | ||
| 4947 | return transCreateNodeNumber(c, lit_bytes, .float); | 4952 | return transCreateNodeNumber(c, lit_bytes, .float); |
| 4948 | } | 4953 | |
| 4949 | const type_node = try Tag.type.create(c.arena, switch (suffix) { | 4954 | const type_node = try Tag.type.create(c.arena, switch (suffix) { |
| 4950 | .f => "f32", | 4955 | .f => "f32", |
| 4951 | .l => "c_longdouble", | 4956 | .l => "c_longdouble", |
| 4952 | else => unreachable, | 4957 | else => unreachable, |
| 4953 | }); | 4958 | }); |
| 4954 | const rhs = try transCreateNodeNumber(c, lit_bytes[0 .. lit_bytes.len - 1], .float); | 4959 | const rhs = try transCreateNodeNumber(c, lit_bytes, .float); |
| 4955 | return Tag.as.create(c.arena, .{ .lhs = type_node, .rhs = rhs }); | 4960 | return Tag.as.create(c.arena, .{ .lhs = type_node, .rhs = rhs }); |
| 4956 | }, | 4961 | }, |
| 4957 | else => unreachable, | 4962 | else => unreachable, |
| ... | @@ -5540,6 +5545,42 @@ fn parseCPostfixExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node { | ... | @@ -5540,6 +5545,42 @@ fn parseCPostfixExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node { |
| 5540 | } | 5545 | } |
| 5541 | }, | 5546 | }, |
| 5542 | .LBrace => { | 5547 | .LBrace => { |
| 5548 | // Check for designated field initializers | ||
| 5549 | if (m.peek().? == .Period) { | ||
| 5550 | var init_vals = std.ArrayList(ast.Payload.ContainerInitDot.Initializer).init(c.gpa); | ||
| 5551 | defer init_vals.deinit(); | ||
| 5552 | |||
| 5553 | while (true) { | ||
| 5554 | if (m.next().? != .Period) { | ||
| 5555 | try m.fail(c, "unable to translate C expr: expected '.'", .{}); | ||
| 5556 | return error.ParseError; | ||
| 5557 | } | ||
| 5558 | if (m.next().? != .Identifier) { | ||
| 5559 | try m.fail(c, "unable to translate C expr: expected identifier", .{}); | ||
| 5560 | return error.ParseError; | ||
| 5561 | } | ||
| 5562 | const name = m.slice(); | ||
| 5563 | if (m.next().? != .Equal) { | ||
| 5564 | try m.fail(c, "unable to translate C expr: expected '='", .{}); | ||
| 5565 | return error.ParseError; | ||
| 5566 | } | ||
| 5567 | |||
| 5568 | const val = try parseCCondExpr(c, m, scope); | ||
| 5569 | try init_vals.append(.{ .name = name, .value = val }); | ||
| 5570 | switch (m.next().?) { | ||
| 5571 | .Comma => {}, | ||
| 5572 | .RBrace => break, | ||
| 5573 | else => { | ||
| 5574 | try m.fail(c, "unable to translate C expr: expected ',' or '}}'", .{}); | ||
| 5575 | return error.ParseError; | ||
| 5576 | }, | ||
| 5577 | } | ||
| 5578 | } | ||
| 5579 | const tuple_node = try Tag.container_init_dot.create(c.arena, try c.arena.dupe(ast.Payload.ContainerInitDot.Initializer, init_vals.items)); | ||
| 5580 | node = try Tag.std_mem_zeroinit.create(c.arena, .{ .lhs = node, .rhs = tuple_node }); | ||
| 5581 | continue; | ||
| 5582 | } | ||
| 5583 | |||
| 5543 | var init_vals = std.ArrayList(Node).init(c.gpa); | 5584 | var init_vals = std.ArrayList(Node).init(c.gpa); |
| 5544 | defer init_vals.deinit(); | 5585 | defer init_vals.deinit(); |
| 5545 | 5586 |
src/translate_c/ast.zig+52-9| ... | @@ -71,6 +71,7 @@ pub const Node = extern union { | ... | @@ -71,6 +71,7 @@ pub const Node = extern union { |
| 71 | array_init, | 71 | array_init, |
| 72 | tuple, | 72 | tuple, |
| 73 | container_init, | 73 | container_init, |
| 74 | container_init_dot, | ||
| 74 | std_meta_cast, | 75 | std_meta_cast, |
| 75 | /// _ = operand; | 76 | /// _ = operand; |
| 76 | discard, | 77 | discard, |
| ... | @@ -332,6 +333,7 @@ pub const Node = extern union { | ... | @@ -332,6 +333,7 @@ pub const Node = extern union { |
| 332 | .ptr_cast, | 333 | .ptr_cast, |
| 333 | .div_exact, | 334 | .div_exact, |
| 334 | .byte_offset_of, | 335 | .byte_offset_of, |
| 336 | .std_meta_cast, | ||
| 335 | => Payload.BinOp, | 337 | => Payload.BinOp, |
| 336 | 338 | ||
| 337 | .integer_literal, | 339 | .integer_literal, |
| ... | @@ -354,7 +356,7 @@ pub const Node = extern union { | ... | @@ -354,7 +356,7 @@ pub const Node = extern union { |
| 354 | .@"struct", .@"union" => Payload.Record, | 356 | .@"struct", .@"union" => Payload.Record, |
| 355 | .tuple => Payload.TupleInit, | 357 | .tuple => Payload.TupleInit, |
| 356 | .container_init => Payload.ContainerInit, | 358 | .container_init => Payload.ContainerInit, |
| 357 | .std_meta_cast => Payload.Infix, | 359 | .container_init_dot => Payload.ContainerInitDot, |
| 358 | .std_meta_promoteIntLiteral => Payload.PromoteIntLiteral, | 360 | .std_meta_promoteIntLiteral => Payload.PromoteIntLiteral, |
| 359 | .block => Payload.Block, | 361 | .block => Payload.Block, |
| 360 | .c_pointer, .single_pointer => Payload.Pointer, | 362 | .c_pointer, .single_pointer => Payload.Pointer, |
| ... | @@ -448,14 +450,6 @@ pub const Node = extern union { | ... | @@ -448,14 +450,6 @@ pub const Node = extern union { |
| 448 | pub const Payload = struct { | 450 | pub const Payload = struct { |
| 449 | tag: Node.Tag, | 451 | tag: Node.Tag, |
| 450 | 452 | ||
| 451 | pub const Infix = struct { | ||
| 452 | base: Payload, | ||
| 453 | data: struct { | ||
| 454 | lhs: Node, | ||
| 455 | rhs: Node, | ||
| 456 | }, | ||
| 457 | }; | ||
| 458 | |||
| 459 | pub const Value = struct { | 453 | pub const Value = struct { |
| 460 | base: Payload, | 454 | base: Payload, |
| 461 | data: []const u8, | 455 | data: []const u8, |
| ... | @@ -600,6 +594,16 @@ pub const Payload = struct { | ... | @@ -600,6 +594,16 @@ pub const Payload = struct { |
| 600 | }; | 594 | }; |
| 601 | }; | 595 | }; |
| 602 | 596 | ||
| 597 | pub const ContainerInitDot = struct { | ||
| 598 | base: Payload, | ||
| 599 | data: []Initializer, | ||
| 600 | |||
| 601 | pub const Initializer = struct { | ||
| 602 | name: []const u8, | ||
| 603 | value: Node, | ||
| 604 | }; | ||
| 605 | }; | ||
| 606 | |||
| 603 | pub const Block = struct { | 607 | pub const Block = struct { |
| 604 | base: Payload, | 608 | base: Payload, |
| 605 | data: struct { | 609 | data: struct { |
| ... | @@ -1893,6 +1897,44 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex { | ... | @@ -1893,6 +1897,44 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex { |
| 1893 | }); | 1897 | }); |
| 1894 | } | 1898 | } |
| 1895 | }, | 1899 | }, |
| 1900 | .container_init_dot => { | ||
| 1901 | const payload = node.castTag(.container_init_dot).?.data; | ||
| 1902 | _ = try c.addToken(.period, "."); | ||
| 1903 | const l_brace = try c.addToken(.l_brace, "{"); | ||
| 1904 | var inits = try c.gpa.alloc(NodeIndex, std.math.max(payload.len, 2)); | ||
| 1905 | defer c.gpa.free(inits); | ||
| 1906 | inits[0] = 0; | ||
| 1907 | inits[1] = 0; | ||
| 1908 | for (payload) |init, i| { | ||
| 1909 | _ = try c.addToken(.period, "."); | ||
| 1910 | _ = try c.addIdentifier(init.name); | ||
| 1911 | _ = try c.addToken(.equal, "="); | ||
| 1912 | inits[i] = try renderNode(c, init.value); | ||
| 1913 | _ = try c.addToken(.comma, ","); | ||
| 1914 | } | ||
| 1915 | _ = try c.addToken(.r_brace, "}"); | ||
| 1916 | |||
| 1917 | if (payload.len < 3) { | ||
| 1918 | return c.addNode(.{ | ||
| 1919 | .tag = .struct_init_dot_two_comma, | ||
| 1920 | .main_token = l_brace, | ||
| 1921 | .data = .{ | ||
| 1922 | .lhs = inits[0], | ||
| 1923 | .rhs = inits[1], | ||
| 1924 | }, | ||
| 1925 | }); | ||
| 1926 | } else { | ||
| 1927 | const span = try c.listToSpan(inits); | ||
| 1928 | return c.addNode(.{ | ||
| 1929 | .tag = .struct_init_dot_comma, | ||
| 1930 | .main_token = l_brace, | ||
| 1931 | .data = .{ | ||
| 1932 | .lhs = span.start, | ||
| 1933 | .rhs = span.end, | ||
| 1934 | }, | ||
| 1935 | }); | ||
| 1936 | } | ||
| 1937 | }, | ||
| 1896 | .container_init => { | 1938 | .container_init => { |
| 1897 | const payload = node.castTag(.container_init).?.data; | 1939 | const payload = node.castTag(.container_init).?.data; |
| 1898 | const lhs = try renderNode(c, payload.lhs); | 1940 | const lhs = try renderNode(c, payload.lhs); |
| ... | @@ -2257,6 +2299,7 @@ fn renderNodeGrouped(c: *Context, node: Node) !NodeIndex { | ... | @@ -2257,6 +2299,7 @@ fn renderNodeGrouped(c: *Context, node: Node) !NodeIndex { |
| 2257 | .array_init, | 2299 | .array_init, |
| 2258 | .tuple, | 2300 | .tuple, |
| 2259 | .container_init, | 2301 | .container_init, |
| 2302 | .container_init_dot, | ||
| 2260 | .block, | 2303 | .block, |
| 2261 | => return c.addNode(.{ | 2304 | => return c.addNode(.{ |
| 2262 | .tag = .grouped_expression, | 2305 | .tag = .grouped_expression, |
test/translate_c.zig+15| ... | @@ -336,6 +336,9 @@ pub fn addCases(cases: *tests.TranslateCContext) void { | ... | @@ -336,6 +336,9 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 336 | \\ int i1; | 336 | \\ int i1; |
| 337 | \\} boom_t; | 337 | \\} boom_t; |
| 338 | \\#define FOO ((boom_t){1}) | 338 | \\#define FOO ((boom_t){1}) |
| 339 | \\typedef struct { float x; } MyCStruct; | ||
| 340 | \\#define A(_x) (MyCStruct) { .x = (_x) } | ||
| 341 | \\#define B A(0.f) | ||
| 339 | , &[_][]const u8{ | 342 | , &[_][]const u8{ |
| 340 | \\pub const struct_Color = extern struct { | 343 | \\pub const struct_Color = extern struct { |
| 341 | \\ r: u8, | 344 | \\ r: u8, |
| ... | @@ -357,6 +360,18 @@ pub fn addCases(cases: *tests.TranslateCContext) void { | ... | @@ -357,6 +360,18 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 357 | \\pub const boom_t = struct_boom_t; | 360 | \\pub const boom_t = struct_boom_t; |
| 358 | , | 361 | , |
| 359 | \\pub const FOO = @import("std").mem.zeroInit(boom_t, .{@as(c_int, 1)}); | 362 | \\pub const FOO = @import("std").mem.zeroInit(boom_t, .{@as(c_int, 1)}); |
| 363 | , | ||
| 364 | \\pub const MyCStruct = extern struct { | ||
| 365 | \\ x: f32, | ||
| 366 | \\}; | ||
| 367 | , | ||
| 368 | \\pub inline fn A(_x: anytype) MyCStruct { | ||
| 369 | \\ return @import("std").mem.zeroInit(MyCStruct, .{ | ||
| 370 | \\ .x = _x, | ||
| 371 | \\ }); | ||
| 372 | \\} | ||
| 373 | , | ||
| 374 | \\pub const B = A(@as(f32, 0.0)); | ||
| 360 | }); | 375 | }); |
| 361 | 376 | ||
| 362 | cases.add("complex switch", | 377 | cases.add("complex switch", |