From 91daf1c8d8a64133f18dcec2b96e9f9f4326fe36 Mon Sep 17 00:00:00 2001 From: Ian Johnson Date: Tue, 4 Jul 2023 00:11:06 -0400 Subject: [PATCH] Autodoc: implement boolean operations --- lib/docs/main.js | 14 +++++++++++++ src/Autodoc.zig | 53 +++++++++++++++++++++++++++++++++++++++++++++++- src/Zir.zig | 4 ++-- 3 files changed, 68 insertions(+), 3 deletions(-) diff --git a/lib/docs/main.js b/lib/docs/main.js index 4d1a935fda..725fe145ee 100644 --- a/lib/docs/main.js +++ b/lib/docs/main.js @@ -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!"); } diff --git a/src/Autodoc.zig b/src/Autodoc.zig index b979aa741c..fd1e064625 100644 --- a/src/Autodoc.zig +++ b/src/Autodoc.zig @@ -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); diff --git a/src/Zir.zig b/src/Zir.zig index d3dc549dcf..230937e1ec 100644 --- a/src/Zir.zig +++ b/src/Zir.zig @@ -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`.