authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2020-03-08 11:26:53+02:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2020-03-08 11:26:53+02:00
log5aa993cd617e0ae3cabc9c626e45a748857e2f2a
tree23d4c5c3f95f0ff22e0be1e834fe647f396aeadd
parent9e60c89601ab205cd3e63215b318beb89ad1b471
signaturelock-open Commit is signed but in an unrecognized format.

translate-c fix nested loops without blocks.


2 files changed, 42 insertions(+), 37 deletions(-)

src-self-hosted/translate_c.zig+20-31
...@@ -2237,6 +2237,7 @@ fn transWhileLoop(...@@ -2237,6 +2237,7 @@ fn transWhileLoop(
2237 .id = .Loop,2237 .id = .Loop,
2238 };2238 };
2239 while_node.body = try transStmt(rp, &loop_scope, ZigClangWhileStmt_getBody(stmt), .unused, .r_value);2239 while_node.body = try transStmt(rp, &loop_scope, ZigClangWhileStmt_getBody(stmt), .unused, .r_value);
2240 _ = try appendToken(rp.c, .Semicolon, ";");
2240 return &while_node.base;2241 return &while_node.base;
2241}2242}
22422243
...@@ -2346,8 +2347,10 @@ fn transForLoop(...@@ -2346,8 +2347,10 @@ fn transForLoop(
2346 try block_scope.?.block_node.statements.push(&while_node.base);2347 try block_scope.?.block_node.statements.push(&while_node.base);
2347 block_scope.?.block_node.rbrace = try appendToken(rp.c, .RBrace, "}");2348 block_scope.?.block_node.rbrace = try appendToken(rp.c, .RBrace, "}");
2348 return &block_scope.?.block_node.base;2349 return &block_scope.?.block_node.base;
2349 } else2350 } else {
2351 _ = try appendToken(rp.c, .Semicolon, ";");
2350 return &while_node.base;2352 return &while_node.base;
2353 }
2351}2354}
23522355
2353fn transSwitch(2356fn transSwitch(
...@@ -5431,6 +5434,8 @@ fn parseCPrimaryExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8,...@@ -5431,6 +5434,8 @@ fn parseCPrimaryExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8,
5431 //else5434 //else
5432 // @as(dest, x)5435 // @as(dest, x)
54335436
5437 const lparen = try appendToken(c, .LParen, "(");
5438
5434 const if_1 = try transCreateNodeIf(c);5439 const if_1 = try transCreateNodeIf(c);
5435 const type_id_1 = try transCreateNodeBuiltinFnCall(c, "@typeInfo");5440 const type_id_1 = try transCreateNodeBuiltinFnCall(c, "@typeInfo");
5436 const type_of_1 = try transCreateNodeBuiltinFnCall(c, "@TypeOf");5441 const type_of_1 = try transCreateNodeBuiltinFnCall(c, "@TypeOf");
...@@ -5492,7 +5497,13 @@ fn parseCPrimaryExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8,...@@ -5492,7 +5497,13 @@ fn parseCPrimaryExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8,
5492 as.rparen_token = try appendToken(c, .RParen, ")");5497 as.rparen_token = try appendToken(c, .RParen, ")");
5493 else_2.body = &as.base;5498 else_2.body = &as.base;
54945499
5495 return &if_1.base;5500 const group_node = try c.a().create(ast.Node.GroupedExpression);
5501 group_node.* = .{
5502 .lparen = lparen,
5503 .expr = &if_1.base,
5504 .rparen = try appendToken(c, .RParen, ")"),
5505 };
5506 return &group_node.base;
5496 },5507 },
5497 else => {5508 else => {
5498 const first_tok = it.list.at(0);5509 const first_tok = it.list.at(0);
...@@ -5545,14 +5556,7 @@ fn parseCSuffixOpExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8,...@@ -5545,14 +5556,7 @@ fn parseCSuffixOpExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8,
5545 );5556 );
5546 return error.ParseError;5557 return error.ParseError;
5547 }5558 }
5548 // deref is often used together with casts so we group the lhs expression5559 const deref = try transCreateNodePtrDeref(c, node);
5549 const group = try c.a().create(ast.Node.GroupedExpression);
5550 group.* = .{
5551 .lparen = try appendToken(c, .LParen, "("),
5552 .expr = node,
5553 .rparen = try appendToken(c, .RParen, ")"),
5554 };
5555 const deref = try transCreateNodePtrDeref(c, &group.base);
5556 node = try transCreateNodeFieldAccess(c, deref, source[name_tok.start..name_tok.end]);5560 node = try transCreateNodeFieldAccess(c, deref, source[name_tok.start..name_tok.end]);
5557 continue;5561 continue;
5558 },5562 },
...@@ -5596,7 +5600,7 @@ fn parseCSuffixOpExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8,...@@ -5596,7 +5600,7 @@ fn parseCSuffixOpExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8,
5596 },5600 },
5597 .Ampersand => {5601 .Ampersand => {
5598 op_token = try appendToken(c, .Ampersand, "&");5602 op_token = try appendToken(c, .Ampersand, "&");
5599 op_id .BitAnd;5603 op_id= .BitAnd;
5600 },5604 },
5601 .Plus => {5605 .Plus => {
5602 op_token = try appendToken(c, .Plus, "+");5606 op_token = try appendToken(c, .Plus, "+");
...@@ -5604,7 +5608,7 @@ fn parseCSuffixOpExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8,...@@ -5604,7 +5608,7 @@ fn parseCSuffixOpExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8,
5604 },5608 },
5605 .Minus => {5609 .Minus => {
5606 op_token = try appendToken(c, .Minus, "-");5610 op_token = try appendToken(c, .Minus, "-");
5607 op_id .Sub;5611 op_id= .Sub;
5608 },5612 },
5609 .AmpersandAmpersand => {5613 .AmpersandAmpersand => {
5610 op_token = try appendToken(c, .Keyword_and, "and");5614 op_token = try appendToken(c, .Keyword_and, "and");
...@@ -5676,19 +5680,17 @@ fn parseCSuffixOpExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8,...@@ -5676,19 +5680,17 @@ fn parseCSuffixOpExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8,
5676 },5680 },
5677 .BangEqual => {5681 .BangEqual => {
5678 op_token = try appendToken(c, .BangEqual, "!=");5682 op_token = try appendToken(c, .BangEqual, "!=");
5679 op_id = .BangEqual;5683 op_id = .BangEqual;
5680 },5684 },
5681 .EqualEqual => {5685 .EqualEqual => {
5682 op_token = try appendToken(c, .EqualEqual, "==");5686 op_token = try appendToken(c, .EqualEqual, "==");
5683 op_id = .EqualEqual;5687 op_id = .EqualEqual;
5684 },5688 },
5685 .Slash => {5689 .Slash => {
5686 // unsigned/float division uses the operator
5687 op_id = .Div;5690 op_id = .Div;
5688 op_token = try appendToken(c, .Slash, "/");5691 op_token = try appendToken(c, .Slash, "/");
5689 },5692 },
5690 .Percent => {5693 .Percent => {
5691 // unsigned/float division uses the operator
5692 op_id = .Mod;5694 op_id = .Mod;
5693 op_token = try appendToken(c, .Percent, "%");5695 op_token = try appendToken(c, .Percent, "%");
5694 },5696 },
...@@ -5729,25 +5731,12 @@ fn parseCPrefixOpExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8,...@@ -5729,25 +5731,12 @@ fn parseCPrefixOpExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8,
5729 return &node.base;5731 return &node.base;
5730 },5732 },
5731 .Asterisk => {5733 .Asterisk => {
5732 // deref is often used together with casts so we group the lhs expression5734 const node = try parseCPrefixOpExpr(c, it, source, source_loc, scope);
5733 const group = try c.a().create(ast.Node.GroupedExpression);5735 return try transCreateNodePtrDeref(c, node);
5734 group.* = .{
5735 .lparen = try appendToken(c, .LParen, "("),
5736 .expr = try parseCPrefixOpExpr(c, it, source, source_loc, scope),
5737 .rparen = try appendToken(c, .RParen, ")"),
5738 };
5739 return try transCreateNodePtrDeref(c, &group.base);
5740 },5736 },
5741 .Ampersand => {5737 .Ampersand => {
5742 // address of is often used together with casts so we group the rhs expression
5743 const node = try transCreateNodePrefixOp(c, .AddressOf, .Ampersand, "&");5738 const node = try transCreateNodePrefixOp(c, .AddressOf, .Ampersand, "&");
5744 const group = try c.a().create(ast.Node.GroupedExpression);5739 node.rhs = try parseCPrefixOpExpr(c, it, source, source_loc, scope);
5745 group.* = .{
5746 .lparen = try appendToken(c, .LParen, "("),
5747 .expr = try parseCPrefixOpExpr(c, it, source, source_loc, scope),
5748 .rparen = try appendToken(c, .RParen, ")"),
5749 };
5750 node.rhs = &group.base;
5751 return &node.base;5740 return &node.base;
5752 },5741 },
5753 else => {5742 else => {
test/translate_c.zig+22-6
...@@ -3,6 +3,22 @@ const std = @import("std");...@@ -3,6 +3,22 @@ const std = @import("std");
3const CrossTarget = std.zig.CrossTarget;3const CrossTarget = std.zig.CrossTarget;
44
5pub fn addCases(cases: *tests.TranslateCContext) void {5pub fn addCases(cases: *tests.TranslateCContext) void {
6 cases.add("nested loops without blocks",
7 \\void foo() {
8 \\ while (0) while (0) {}
9 \\ for (;;) while (0);
10 \\ for (;;) do {} while (0);
11 \\}
12 , &[_][]const u8{
13 \\pub export fn foo() void {
14 \\ while (@as(c_int, 0) != 0) while (@as(c_int, 0) != 0) {};
15 \\ while (true) while (@as(c_int, 0) != 0) {};
16 \\ while (true) while (true) {
17 \\ if (!(@as(c_int, 0) != 0)) break;
18 \\ };
19 \\}
20 });
21
6 cases.add("macro comma operator",22 cases.add("macro comma operator",
7 \\#define foo (foo, bar)23 \\#define foo (foo, bar)
8 \\#define bar(x) (&x, +3, 4 == 4, 5 * 6, baz(1, 2), 2 % 2, baz(1,2))24 \\#define bar(x) (&x, +3, 4 == 4, 5 * 6, baz(1, 2), 2 % 2, baz(1,2))
...@@ -14,7 +30,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -14,7 +30,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
14 ,30 ,
15 \\pub inline fn bar(x: var) @TypeOf(baz(1, 2)) {31 \\pub inline fn bar(x: var) @TypeOf(baz(1, 2)) {
16 \\ return blk: {32 \\ return blk: {
17 \\ _ = &(x);33 \\ _ = &x;
18 \\ _ = 3;34 \\ _ = 3;
19 \\ _ = 4 == 4;35 \\ _ = 4 == 4;
20 \\ _ = 5 * 6;36 \\ _ = 5 * 6;
...@@ -1404,7 +1420,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -1404,7 +1420,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
1404 cases.add("macro pointer cast",1420 cases.add("macro pointer cast",
1405 \\#define NRF_GPIO ((NRF_GPIO_Type *) NRF_GPIO_BASE)1421 \\#define NRF_GPIO ((NRF_GPIO_Type *) NRF_GPIO_BASE)
1406 , &[_][]const u8{1422 , &[_][]const u8{
1407 \\pub const NRF_GPIO = if (@typeInfo(@TypeOf(NRF_GPIO_BASE)) == .Pointer) @ptrCast([*c]NRF_GPIO_Type, NRF_GPIO_BASE) else if (@typeInfo(@TypeOf(NRF_GPIO_BASE)) == .Int) @intToPtr([*c]NRF_GPIO_Type, NRF_GPIO_BASE) else @as([*c]NRF_GPIO_Type, NRF_GPIO_BASE);1423 \\pub const NRF_GPIO = (if (@typeInfo(@TypeOf(NRF_GPIO_BASE)) == .Pointer) @ptrCast([*c]NRF_GPIO_Type, NRF_GPIO_BASE) else if (@typeInfo(@TypeOf(NRF_GPIO_BASE)) == .Int) @intToPtr([*c]NRF_GPIO_Type, NRF_GPIO_BASE) else @as([*c]NRF_GPIO_Type, NRF_GPIO_BASE));
1408 });1424 });
14091425
1410 cases.add("basic macro function",1426 cases.add("basic macro function",
...@@ -1993,7 +2009,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -1993,7 +2009,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
1993 ,2009 ,
1994 \\pub const DOT = a.b;2010 \\pub const DOT = a.b;
1995 ,2011 ,
1996 \\pub const ARROW = (a).*.b;2012 \\pub const ARROW = a.*.b;
1997 });2013 });
19982014
1999 cases.add("array access",2015 cases.add("array access",
...@@ -2588,11 +2604,11 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -2588,11 +2604,11 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
2588 \\#define FOO(bar) baz((void *)(baz))2604 \\#define FOO(bar) baz((void *)(baz))
2589 \\#define BAR (void*) a2605 \\#define BAR (void*) a
2590 , &[_][]const u8{2606 , &[_][]const u8{
2591 \\pub inline fn FOO(bar: var) @TypeOf(baz(if (@typeInfo(@TypeOf(baz)) == .Pointer) @ptrCast(*c_void, baz) else if (@typeInfo(@TypeOf(baz)) == .Int) @intToPtr(*c_void, baz) else @as(*c_void, baz))) {2607 \\pub inline fn FOO(bar: var) @TypeOf(baz((if (@typeInfo(@TypeOf(baz)) == .Pointer) @ptrCast(*c_void, baz) else if (@typeInfo(@TypeOf(baz)) == .Int) @intToPtr(*c_void, baz) else @as(*c_void, baz)))) {
2592 \\ return baz(if (@typeInfo(@TypeOf(baz)) == .Pointer) @ptrCast(*c_void, baz) else if (@typeInfo(@TypeOf(baz)) == .Int) @intToPtr(*c_void, baz) else @as(*c_void, baz));2608 \\ return baz((if (@typeInfo(@TypeOf(baz)) == .Pointer) @ptrCast(*c_void, baz) else if (@typeInfo(@TypeOf(baz)) == .Int) @intToPtr(*c_void, baz) else @as(*c_void, baz)));
2593 \\}2609 \\}
2594 ,2610 ,
2595 \\pub const BAR = if (@typeInfo(@TypeOf(a)) == .Pointer) @ptrCast(*c_void, a) else if (@typeInfo(@TypeOf(a)) == .Int) @intToPtr(*c_void, a) else @as(*c_void, a);2611 \\pub const BAR = (if (@typeInfo(@TypeOf(a)) == .Pointer) @ptrCast(*c_void, a) else if (@typeInfo(@TypeOf(a)) == .Int) @intToPtr(*c_void, a) else @as(*c_void, a));
2596 });2612 });
25972613
2598 cases.add("macro conditional operator",2614 cases.add("macro conditional operator",