Zig 0.17.0-dev (Split by item)

This is an example of documentation generated by ZigDoc, an alternative to Zig's built-in Auto Doc feature. See also examples in other modes/formats. The project being documented here (as the example) is the Zig library itself.

transDoWhileStmt

Translator.transDoWhileStmt
fn transDoWhileStmt(t: *Translator, scope: *Scope, do_stmt: Node.DoWhileStmt) TransError!ZigNode

File

lib/compiler/translate-c/Translator.zig:1822

Code

fn transDoWhileStmt(t: *Translator, scope: *Scope, do_stmt: Node.DoWhileStmt) TransError!ZigNode {
    var loop_scope: Scope = .{
        .parent = scope,
        .id = .do_loop,
    };

    // if (!cond) break;
    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()) {
        // The body node ends in a noreturn statement. Simply put it in a while (true)
        // in case it contains breaks or continues.
    } else if (do_stmt.body.get(t.tree) == .compound_stmt) {
        // there's already a block in C, so we'll append our condition to it.
        // 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; // This is safe since we reserve one extra space in Scope.Block.complete.
        block.data.stmts[block.data.stmts.len - 1] = if_not_break;
    } else {
        // the C statement is without a block, so we need to create a block to contain it.
        // 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);
}