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 {...@@ -54,6 +54,7 @@ const Scope = struct {
5454
55 const Switch = struct {55 const Switch = struct {
56 base: Scope,56 base: Scope,
57 label: []const u8,
57 };58 };
5859
59 /// used when getting a member `a.b`60 /// used when getting a member `a.b`
...@@ -190,6 +191,7 @@ const Scope = struct {...@@ -190,6 +191,7 @@ const Scope = struct {
190 .Ref => null,191 .Ref => null,
191 .FnDef => @fieldParentPtr(FnDef, "base", scope).getAlias(name),192 .FnDef => @fieldParentPtr(FnDef, "base", scope).getAlias(name),
192 .Block => @fieldParentPtr(Block, "base", scope).getAlias(name),193 .Block => @fieldParentPtr(Block, "base", scope).getAlias(name),
194 .Condition => scope.parent.?.getAlias(name),
193 else => @panic("TODO Scope.getAlias"),195 else => @panic("TODO Scope.getAlias"),
194 };196 };
195 }197 }
...@@ -200,9 +202,15 @@ const Scope = struct {...@@ -200,9 +202,15 @@ const Scope = struct {
200 .Root => @fieldParentPtr(Root, "base", scope).contains(name),202 .Root => @fieldParentPtr(Root, "base", scope).contains(name),
201 .FnDef => @fieldParentPtr(FnDef, "base", scope).contains(name),203 .FnDef => @fieldParentPtr(FnDef, "base", scope).contains(name),
202 .Block => @fieldParentPtr(Block, "base", scope).contains(name),204 .Block => @fieldParentPtr(Block, "base", scope).contains(name),
205 .Condition => scope.parent.?.contains(name),
203 else => @panic("TODO Scope.contains"),206 else => @panic("TODO Scope.contains"),
204 };207 };
205 }208 }
209
210 fn getBreakableScope(scope: *Scope) *Scope {
211 var scope = inner;
212 while (scope.id != .Switch and scope.id != .Root) : (scope = scope.parent.?) {}
213 }
206};214};
207215
208const Context = struct {216const Context = struct {
...@@ -613,6 +621,13 @@ fn transStmt(...@@ -613,6 +621,13 @@ fn transStmt(
613 .IfStmtClass => return transIfStmt(rp, scope, @ptrCast(*const ZigClangIfStmt, stmt)),621 .IfStmtClass => return transIfStmt(rp, scope, @ptrCast(*const ZigClangIfStmt, stmt)),
614 .WhileStmtClass => return transWhileLoop(rp, scope, @ptrCast(*const ZigClangWhileStmt, stmt)),622 .WhileStmtClass => return transWhileLoop(rp, scope, @ptrCast(*const ZigClangWhileStmt, stmt)),
615 .DoStmtClass => return transDoWhileLoop(rp, scope, @ptrCast(*const ZigClangDoStmt, stmt)),623 .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),
616 else => {631 else => {
617 return revertAndWarn(632 return revertAndWarn(
618 rp,633 rp,
...@@ -1241,7 +1256,7 @@ fn transDoWhileLoop(...@@ -1241,7 +1256,7 @@ fn transDoWhileLoop(
1241 _ = try appendToken(rp.c, .RParen, ")");1256 _ = try appendToken(rp.c, .RParen, ")");
1242 var new = false;1257 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: {
1245 // there's already a block in C, so we'll append our condition to it.1260 // there's already a block in C, so we'll append our condition to it.
1246 // c: do {1261 // c: do {
1247 // c: a;1262 // c: a;
...@@ -1252,8 +1267,8 @@ fn transDoWhileLoop(...@@ -1252,8 +1267,8 @@ fn transDoWhileLoop(
1252 // zig: b;1267 // zig: b;
1253 // zig: if (!cond) break;1268 // zig: if (!cond) break;
1254 // zig: }1269 // zig: }
1255 (try transStmt(rp, scope, ZigClangDoStmt_getBody(stmt), .unused, .r_value)).cast(ast.Node.Block).?1270 break :blk (try transStmt(rp, scope, ZigClangDoStmt_getBody(stmt), .unused, .r_value)).cast(ast.Node.Block).?
1256 else blk: {1271 } else blk: {
1257 // the C statement is without a block, so we need to create a block to contain it.1272 // the C statement is without a block, so we need to create a block to contain it.
1258 // c: do1273 // c: do
1259 // c: a;1274 // c: a;
...@@ -1262,7 +1277,6 @@ fn transDoWhileLoop(...@@ -1262,7 +1277,6 @@ fn transDoWhileLoop(
1262 // zig: a;1277 // zig: a;
1263 // zig: if (!cond) break;1278 // zig: if (!cond) break;
1264 // zig: }1279 // zig: }
1265
1266 new = true;1280 new = true;
1267 const block = try transCreateNodeBlock(rp.c, null);1281 const block = try transCreateNodeBlock(rp.c, null);
1268 try block.statements.push(try transStmt(rp, scope, ZigClangDoStmt_getBody(stmt), .unused, .r_value));1282 try block.statements.push(try transStmt(rp, scope, ZigClangDoStmt_getBody(stmt), .unused, .r_value));
...@@ -1328,6 +1342,15 @@ fn transCPtrCast(...@@ -1328,6 +1342,15 @@ fn transCPtrCast(
1328 return &ptrcast_node.base;1342 return &ptrcast_node.base;
1329}1343}
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
1331fn maybeSuppressResult(1354fn maybeSuppressResult(
1332 rp: RestorePoint,1355 rp: RestorePoint,
1333 scope: *Scope,1356 scope: *Scope,
...@@ -2165,6 +2188,18 @@ fn transCreateNodeWhile(c: *Context) !*ast.Node.While {...@@ -2165,6 +2188,18 @@ fn transCreateNodeWhile(c: *Context) !*ast.Node.While {
2165 return node;2188 return node;
2166}2189}
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
2168const RestorePoint = struct {2203const RestorePoint = struct {
2169 c: *Context,2204 c: *Context,
2170 token_index: ast.TokenIndex,2205 token_index: ast.TokenIndex,