Commit 91daf1c8d8

Ian Johnson <ian@ianjohnson.dev>
2023-07-04 06:11:06
Autodoc: implement boolean operations
1 parent 8ce68e5
Changed files (3)
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!");
         }
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);
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`.