authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2019-12-16 23:54:16+02:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2019-12-16 23:54:16+02:00
logd54bcb2b62fe6cc7212bf370bcd257aaf1dfff8b
tree63c5ae9c0a6d384076d780b93657ac38fafe816d
parent6a3d48353b14ff234484887258cfab5ef51fdea0
signature Commit is signed but in an unrecognized format.

translate-c-2 break and continue


1 files changed, 39 insertions(+), 4 deletions(-)

src-self-hosted/translate_c.zig+39-4
......@@ -54,6 +54,7 @@ const Scope = struct {
5454
5555 const Switch = struct {
5656 base: Scope,
57 label: []const u8,
5758 };
5859
5960 /// used when getting a member `a.b`
......@@ -190,6 +191,7 @@ const Scope = struct {
190191 .Ref => null,
191192 .FnDef => @fieldParentPtr(FnDef, "base", scope).getAlias(name),
192193 .Block => @fieldParentPtr(Block, "base", scope).getAlias(name),
194 .Condition => scope.parent.?.getAlias(name),
193195 else => @panic("TODO Scope.getAlias"),
194196 };
195197 }
......@@ -200,9 +202,15 @@ const Scope = struct {
200202 .Root => @fieldParentPtr(Root, "base", scope).contains(name),
201203 .FnDef => @fieldParentPtr(FnDef, "base", scope).contains(name),
202204 .Block => @fieldParentPtr(Block, "base", scope).contains(name),
205 .Condition => scope.parent.?.contains(name),
203206 else => @panic("TODO Scope.contains"),
204207 };
205208 }
209
210 fn getBreakableScope(scope: *Scope) *Scope {
211 var scope = inner;
212 while (scope.id != .Switch and scope.id != .Root) : (scope = scope.parent.?) {}
213 }
206214};
207215
208216const Context = struct {
......@@ -613,6 +621,13 @@ fn transStmt(
613621 .IfStmtClass => return transIfStmt(rp, scope, @ptrCast(*const ZigClangIfStmt, stmt)),
614622 .WhileStmtClass => return transWhileLoop(rp, scope, @ptrCast(*const ZigClangWhileStmt, stmt)),
615623 .DoStmtClass => return transDoWhileLoop(rp, scope, @ptrCast(*const ZigClangDoStmt, stmt)),
624 .NullStmtClass => {
625 const block = try transCreateNodeBlock(rp.c, null);
626 block.rbrace = try appendToken(rp.c, .RBrace, "}");
627 return &block.base;
628 },
629 .ContinueStmtClass => return transCreateNodeContinue(rp.c),
630 .BreakStmtClass => return transBreak(rp, scope),
616631 else => {
617632 return revertAndWarn(
618633 rp,
......@@ -1241,7 +1256,7 @@ fn transDoWhileLoop(
12411256 _ = try appendToken(rp.c, .RParen, ")");
12421257 var new = false;
12431258
1244 const body_node = if (ZigClangStmt_getStmtClass(ZigClangDoStmt_getBody(stmt)) == .CompoundStmtClass)
1259 const body_node = if (ZigClangStmt_getStmtClass(ZigClangDoStmt_getBody(stmt)) == .CompoundStmtClass) blk: {
12451260 // there's already a block in C, so we'll append our condition to it.
12461261 // c: do {
12471262 // c: a;
......@@ -1252,8 +1267,8 @@ fn transDoWhileLoop(
12521267 // zig: b;
12531268 // zig: if (!cond) break;
12541269 // zig: }
1255 (try transStmt(rp, scope, ZigClangDoStmt_getBody(stmt), .unused, .r_value)).cast(ast.Node.Block).?
1256 else blk: {
1270 break :blk (try transStmt(rp, scope, ZigClangDoStmt_getBody(stmt), .unused, .r_value)).cast(ast.Node.Block).?
1271 } else blk: {
12571272 // the C statement is without a block, so we need to create a block to contain it.
12581273 // c: do
12591274 // c: a;
......@@ -1262,7 +1277,6 @@ fn transDoWhileLoop(
12621277 // zig: a;
12631278 // zig: if (!cond) break;
12641279 // zig: }
1265
12661280 new = true;
12671281 const block = try transCreateNodeBlock(rp.c, null);
12681282 try block.statements.push(try transStmt(rp, scope, ZigClangDoStmt_getBody(stmt), .unused, .r_value));
......@@ -1328,6 +1342,15 @@ fn transCPtrCast(
13281342 return &ptrcast_node.base;
13291343}
13301344
1345fn transBreak(rp: RestorePoint, scope: *Scope) TransError!*ast.Node {
1346 const break_scope = scope.getBreakableScope();
1347 const br = try transCreateNodeBreak(rp.c, if (break_scope.id == .Switch)
1348 @fieldParentPtr(Scope.Switch, "base", break_scope).label
1349 else
1350 null);
1351 return &br.base;
1352}
1353
13311354fn maybeSuppressResult(
13321355 rp: RestorePoint,
13331356 scope: *Scope,
......@@ -2165,6 +2188,18 @@ fn transCreateNodeWhile(c: *Context) !*ast.Node.While {
21652188 return node;
21662189}
21672190
2191fn transCreateNodeContinue(c: *Context) !*ast.Node {
2192 const ltoken = try appendToken(c, .Keyword_continue, "continue");
2193 const node = try c.a().create(ast.Node.ControlFlowExpression);
2194 node.* = .{
2195 .ltoken = ltoken,
2196 .kind = .{ .Continue = null },
2197 .rhs = null,
2198 };
2199 _ = try appendToken(rp.c, .Semicolon, ";");
2200 return &node.base;
2201}
2202
21682203const RestorePoint = struct {
21692204 c: *Context,
21702205 token_index: ast.TokenIndex,