feature. See also
. The project being documented here (as the example) is the Zig library itself.
Translator.transBinaryCondExpr
fn transBinaryCondExpr(
t: *Translator,
scope: *Scope,
conditional: Node.Conditional,
used: ResultUsed,
) TransError!ZigNode
File
Code
fn transBinaryCondExpr(
t: *Translator,
scope: *Scope,
conditional: Node.Conditional,
used: ResultUsed,
) TransError!ZigNode {
// omitted, the condition itself is returned if it evaluates to true.
if (used == .unused) {
// 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);
// 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();
}