feature. See also
. The project being documented here (as the example) is the Zig library itself.
Translator.transDoWhileStmt
fn transDoWhileStmt(t: *Translator, scope: *Scope, do_stmt: Node.DoWhileStmt) TransError!ZigNode
File
Code
fn transDoWhileStmt(t: *Translator, scope: *Scope, do_stmt: Node.DoWhileStmt) TransError!ZigNode {
var loop_scope: Scope = .{
.parent = scope,
.id = .do_loop,
};
var cond_scope: Scope.Condition = .{
.base = .{
.parent = scope,
.id = .condition,
},
};
defer cond_scope.deinit();
const cond = try t.transBoolExpr(&cond_scope.base, do_stmt.cond);
const if_not_break = switch (cond.tag()) {
.true_literal => {
const body_node = try t.maybeBlockify(scope, do_stmt.body);
return ZigTag.while_true.create(t.arena, body_node);
},
else => try ZigTag.if_not_break.create(t.arena, cond),
};
var body_node = try t.transStmt(&loop_scope, do_stmt.body);
if (body_node.isNoreturn()) {
// in case it contains breaks or continues.
} else if (do_stmt.body.get(t.tree) == .compound_stmt) {
// c: do {
// c: a;
// c: b;
// c: } while(c);
// zig: while (true) {
// zig: a;
// zig: b;
// zig: if (!cond) break;
// zig: }
const block = body_node.castTag(.block).?;
block.data.stmts.len += 1;
block.data.stmts[block.data.stmts.len - 1] = if_not_break;
} else {
// c: do
// c: a;
// c: while(c);
// zig: while (true) {
// zig: a;
// zig: if (!cond) break;
// zig: }
const statements = try t.arena.alloc(ZigNode, 2);
statements[0] = body_node;
statements[1] = if_not_break;
body_node = try ZigTag.block.create(t.arena, .{ .label = null, .stmts = statements });
}
return ZigTag.while_true.create(t.arena, body_node);
}