Autodoc: implement boolean operations

This commit is contained in:
Ian Johnson 2023-07-04 00:11:06 -04:00 committed by Loris Cro
parent 8ce68e5f41
commit 91daf1c8d8
3 changed files with 68 additions and 3 deletions

View File

@ -1078,6 +1078,9 @@ Happy writing!
case "void": {
return "void";
}
case "unreachable": {
return "unreachable";
}
case "slice": {
let payloadHtml = "";
const lhsExpr = zigAnalysis.exprs[expr.slice.lhs];
@ -1386,6 +1389,9 @@ Happy writing!
case "bit_not": {
return "~" + param;
}
case "bool_not": {
return "!" + param;
}
case "clz": {
return "@clz(T" + ", " + param + ")";
}
@ -1657,6 +1663,14 @@ Happy writing!
operator += "<=";
break;
}
case "bool_br_and": {
operator += "and";
break;
}
case "bool_br_or": {
operator += "or";
break;
}
default:
console.log("operator not handled yet or doesn't exist!");
}

View File

@ -797,7 +797,7 @@ const DocData = struct {
}
};
/// An Expr represents the (untyped) result of analizing instructions.
/// An Expr represents the (untyped) result of analyzing instructions.
/// The data is normalized, which means that an Expr that results in a
/// type definition will hold an index into `self.types`.
pub const Expr = union(enum) {
@ -1262,6 +1262,12 @@ fn walkInstruction(
.expr = .{ .int_big = .{ .value = as_string } },
};
},
.@"unreachable" => {
return DocData.WalkResult{
.typeRef = .{ .type = @intFromEnum(Ref.noreturn_type) },
.expr = .{ .@"unreachable" = .{} },
};
},
.slice_start => {
const pl_node = data[inst_index].pl_node;
@ -1580,6 +1586,7 @@ fn walkInstruction(
.frame_size,
.int_from_ptr,
.bit_not,
.bool_not,
// @check
.clz,
.ctz,
@ -1602,6 +1609,40 @@ fn walkInstruction(
.expr = .{ .builtinIndex = bin_index },
};
},
.bool_br_and, .bool_br_or => {
const bool_br = data[inst_index].bool_br;
const bin_index = self.exprs.items.len;
try self.exprs.append(self.arena, .{ .binOp = .{ .lhs = 0, .rhs = 0 } });
const lhs = try self.walkRef(
file,
parent_scope,
parent_src,
bool_br.lhs,
false,
);
const lhs_index = self.exprs.items.len;
try self.exprs.append(self.arena, lhs.expr);
const extra = file.zir.extraData(Zir.Inst.Block, bool_br.payload_index);
const rhs = try self.walkInstruction(
file,
parent_scope,
parent_src,
file.zir.extra[extra.end..][extra.data.body_len - 1],
false,
);
const rhs_index = self.exprs.items.len;
try self.exprs.append(self.arena, rhs.expr);
self.exprs.items[bin_index] = .{ .binOp = .{ .name = @tagName(tags[inst_index]), .lhs = lhs_index, .rhs = rhs_index } };
return DocData.WalkResult{
.typeRef = .{ .type = @intFromEnum(Ref.bool_type) },
.expr = .{ .binOpIndex = bin_index },
};
},
.truncate => {
// in the ZIR this node is a builtin `bin` but we want send it as a `un` builtin
const pl_node = data[inst_index].pl_node;
@ -2359,6 +2400,16 @@ fn walkInstruction(
need_type,
);
},
.break_inline => {
const @"break" = data[inst_index].@"break";
return try self.walkRef(
file,
parent_scope,
parent_src,
@"break".operand,
need_type,
);
},
.struct_init => {
const pl_node = data[inst_index].pl_node;
const extra = file.zir.extraData(Zir.Inst.StructInit, pl_node.payload_index);

View File

@ -255,7 +255,7 @@ pub const Inst = struct {
/// Uses the pl_node field with payload `Bin`.
bitcast,
/// Bitwise NOT. `~`
/// Uses `un_tok`.
/// Uses `un_node`.
bit_not,
/// Bitwise OR. `|`
bit_or,
@ -274,7 +274,7 @@ pub const Inst = struct {
/// Uses the `pl_node` union field. Payload is `Block`.
suspend_block,
/// Boolean NOT. See also `bit_not`.
/// Uses the `un_tok` field.
/// Uses the `un_node` field.
bool_not,
/// Short-circuiting boolean `and`. `lhs` is a boolean `Ref` and the other operand
/// is a block, which is evaluated if `lhs` is `true`.