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.

transBinaryCondExpr

Translator.transBinaryCondExpr
fn transBinaryCondExpr(
    t: *Translator,
    scope: *Scope,
    conditional: Node.Conditional,
    used: ResultUsed,
) TransError!ZigNode

File

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

Code

fn transBinaryCondExpr(
    t: *Translator,
    scope: *Scope,
    conditional: Node.Conditional,
    used: ResultUsed,
) TransError!ZigNode {
    // GNU extension of the ternary operator where the middle expression is
    // omitted, the condition itself is returned if it evaluates to true.

    if (used == .unused) {
        // Result unused so this can be translated as
        // if (condition) else_expr;
        var cond_scope: Scope.Condition = .{
            .base = .{
                .parent = scope,
                .id = .condition,
            },
        };
        defer cond_scope.deinit();

        return ZigTag.@"if".create(t.arena, .{
            .cond = try t.transBoolExpr(&cond_scope.base, conditional.cond),
            .then = try t.transExpr(scope, conditional.else_expr, .unused),
            .@"else" = null,
        });
    }

    const res_is_bool = conditional.qt.is(t.comp, .bool);
    // c:   (condition)?:(else_expr)
    // zig: (blk: {
    //          const _cond_temp = (condition);
    //          break :blk if (_cond_temp) _cond_temp else (else_expr);
    //      })
    var block_scope = try Scope.Block.init(t, scope, true);
    defer block_scope.deinit();

    const cond_temp = try block_scope.reserveMangledName("cond_temp");
    const init_node = try t.transExpr(&block_scope.base, conditional.cond, .used);
    const temp_decl = try ZigTag.var_simple.create(t.arena, .{ .name = cond_temp, .init = init_node });
    try block_scope.statements.append(t.gpa, temp_decl);

    var cond_scope: Scope.Condition = .{
        .base = .{
            .parent = &block_scope.base,
            .id = .condition,
        },
    };
    defer cond_scope.deinit();

    const cond_ident = try ZigTag.identifier.create(t.arena, cond_temp);
    const cond_node = try t.finishBoolExpr(conditional.cond.qt(t.tree), cond_ident);
    var then_body = cond_ident;
    if (!res_is_bool and init_node.isBoolRes()) {
        then_body = try ZigTag.int_from_bool.create(t.arena, then_body);
    }

    var else_body = try t.transExpr(&block_scope.base, conditional.else_expr, .used);
    if (!res_is_bool and else_body.isBoolRes()) {
        else_body = try ZigTag.int_from_bool.create(t.arena, else_body);
    }
    const if_node = try ZigTag.@"if".create(t.arena, .{
        .cond = cond_node,
        .then = then_body,
        .@"else" = else_body,
    });
    const break_node = try ZigTag.break_val.create(t.arena, .{
        .label = block_scope.label,
        .val = if_node,
    });
    try block_scope.statements.append(t.gpa, break_node);
    return block_scope.complete();
}