Commit f2026e7dd6

Krzysztof Wolicki <der.teufel.mail@gmail.com>
2023-09-12 17:50:40
autodoc: Implement builtin function rendering. Implement unary ops handling. Fix getType in main.js Minor cleanup of builtin function handling.
1 parent 9a326b2
Changed files (2)
lib
docs
src
lib/docs/main.js
@@ -1522,6 +1522,47 @@ Happy writing!
         return;
       }
 
+      case "unOpIndex": {
+        const unOp = zigAnalysis.exprs[expr.unOpIndex];
+        yield* ex(unOp, opts);
+        return;
+      }
+
+      case "unOp": {
+        const param = zigAnalysis.exprs[expr.unOp.param];
+
+        switch (expr.unOp.name) {
+          case "bit_not": {
+            yield { src: "~", tag: Tag.tilde };
+            break;
+          }
+          case "bool_not": {
+            yield { src: "!", tag: Tag.bang };
+            break;
+          }
+          case "negate_wrap": {
+            yield { src: "-%", tag: Tag.minus_percent };
+            break;
+          }
+          case "negate": {
+            yield { src: "-", tag: Tag.minus };
+            break;
+          }
+          default:
+            throw "unOp: `" + expr.unOp.name + "` not implemented yet!"
+        }
+
+        if (param["binOpIndex"] !== undefined) {
+          yield Tok.l_paren;
+          yield* ex(param, opts);
+          yield Tok.r_paren;
+        } else {
+          yield* ex(param, opts);
+        }
+        
+        return;
+      }
+
       case "binOpIndex": {
         const binOp = zigAnalysis.exprs[expr.binOpIndex];
         yield* ex(binOp, opts);
@@ -1669,6 +1710,52 @@ Happy writing!
         return;
       }
 
+      case "builtin": {
+        const builtin = expr.builtin;
+        let name = "@";
+        const param = zigAnalysis.exprs[builtin.param];
+        switch (builtin.name) {
+          case "align_of": { name += "alignOf"; break; }
+          case "int_from_bool": { name += "intFromBool"; break; }
+          case "embed_file": { name += "embedFile"; break; }
+          case "error_name": { name += "errorName"; break; }
+          case "panic": { name += "panic"; break; }
+          case "set_runtime_safety": { name += "setRuntimeSafety"; break; }
+          case "sqrt": { name += "sqrt"; break; }
+          case "sin": { name += "sin"; break; }
+          case "cos": { name += "cos"; break; }
+          case "tan": { name += "tan"; break; }
+          case "exp": { name += "exp"; break; }
+          case "exp2": { name += "exp2"; break; }
+          case "log": { name += "log"; break; }
+          case "log2": { name += "log2"; break; }
+          case "log10": { name += "log10"; break; }
+          case "fabs": { name += "fabs"; break; }
+          case "floor": { name += "floor"; break; }
+          case "ceil": { name += "ceil"; break; }
+          case "trunc": { name += "trunc"; break; }
+          case "round": { name += "round"; break; }
+          case "tag_name": { name += "tagName"; break; }
+          case "type_name": { name += "typeName"; break; }
+          case "type_info": { name += "typeInfo"; break; }
+          case "frame_type": { name += "Frame"; break; }
+          case "frame_size": { name += "frameSize"; break; }
+          case "int_from_ptr": { name += "intFromPtr"; break; }
+          case "int_from_enum": { name += "intFromEnum"; break; }
+          case "clz": { name += "clz"; break; }
+          case "ctz": { name += "ctz"; break; }
+          case "pop_count": { name += "popCount"; break; }
+          case "byte_swap": { name += "byteSwap"; break; }
+          case "bit_reverse": { name += "bitReverse"; break; }
+          default: throw "builtin: `" + builtin.name + "` not implemented yet!";
+        }
+        yield { src: name, tag: Tag.builtin };
+        yield Tok.l_paren;
+        yield* ex(param, opts);
+        yield Tok.r_paren;
+        return;
+      }
+
       case "builtinBinIndex": {
         const builtinBinIndex = zigAnalysis.exprs[expr.builtinBinIndex];
         yield* ex(builtinBinIndex, opts);
@@ -1899,15 +1986,6 @@ Happy writing!
         return;
       }
 
-      case "typeInfo": {
-        const arg = zigAnalysis.exprs[expr.typeInfo];
-        yield { src: "@typeInfo", tag: Tag.builtin };
-        yield Tok.l_paren;
-        yield* ex(arg, opts);
-        yield Tok.r_paren;
-        return;
-      }
-
       case "switchIndex": {
         const switchIndex = zigAnalysis.exprs[expr.switchIndex];
         yield* ex(switchIndex, opts);
@@ -4560,16 +4638,16 @@ Happy writing!
     switch (ty[0]) {
       default:
         throw "unhandled type kind!";
-      case 0: // Unanalyzed
+      case typeKinds.Unanalyzed:
         throw "unanalyzed type!";
-      case 1: // Type
-      case 2: // Void 
-      case 3: //  Bool
-      case 4: //  NoReturn
-      case 5: //  Int
-      case 6: //  Float
+      case typeKinds.Type:
+      case typeKinds.Void:
+      case typeKinds.Bool:
+      case typeKinds.NoReturn:
+      case typeKinds.Int:
+      case typeKinds.Float:
         return { kind: ty[0], name: ty[1] };
-      case 7: // Pointer
+      case typeKinds.Pointer:
         return {
           kind: ty[0],
           size: ty[1],
@@ -4588,14 +4666,14 @@ Happy writing!
           has_addrspace: ty[14],
           has_bit_range: ty[15],
         };
-      case 8: // Array
+      case typeKinds.Array:
         return {
           kind: ty[0],
           len: ty[1],
           child: ty[2],
           sentinel: ty[3],
         };
-      case 9: // Struct
+      case typeKinds.Struct:
         return {
           kind: ty[0],
           name: ty[1],
@@ -4610,36 +4688,36 @@ Happy writing!
           parent_container: ty[10],
           layout: ty[11],
         };
-      case 10: // ComptimeExpr
-      case 11: // ComptimeFloat
-      case 12: // ComptimeInt
-      case 13: // Undefined
-      case 14: // Null
+      case typeKinds.ComptimeExpr:
+      case typeKinds.ComptimeFloat:
+      case typeKinds.ComptimeInt:
+      case typeKinds.Undefined:
+      case typeKinds.Null:
         return { kind: ty[0], name: ty[1] };
-      case 15: // Optional
+      case typeKinds.Optional:
         return {
           kind: ty[0],
           name: ty[1],
           child: ty[2],
         };
-      case 16: // ErrorUnion
+      case typeKinds.ErrorUnion:
         return {
           kind: ty[0],
           lhs: ty[1],
           rhs: ty[2],
         };
-      case 17: // InferredErrorUnion
+      case typeKinds.InferredErrorUnion:
         return {
           kind: ty[0],
           payload: ty[1],
         };
-      case 18: // ErrorSet
+      case typeKinds.ErrorSet:
         return {
           kind: ty[0],
           name: ty[1],
           fields: ty[2],
         };
-      case 19: // Enum
+      case typeKinds.Enum:
         return {
           kind: ty[0],
           name: ty[1],
@@ -4651,7 +4729,7 @@ Happy writing!
           nonexhaustive: ty[7],
           parent_container: ty[8],
         };
-      case 20: // Union
+      case typeKinds.Union:
         return {
           kind: ty[0],
           name: ty[1],
@@ -4664,7 +4742,7 @@ Happy writing!
           parent_container: ty[8],
           layout: ty[9],
         };
-      case 21: // Fn
+      case typeKinds.Fn:
         return {
           kind: ty[0],
           name: ty[1],
@@ -4683,9 +4761,7 @@ Happy writing!
           is_test: ty[14],
           is_extern: ty[15],
         };
-      case 22: // BoundFn
-        return { kind: ty[0], name: ty[1] };
-      case 23: // Opaque
+      case typeKinds.Opaque:
         return {
           kind: ty[0],
           name: ty[1],
@@ -4694,10 +4770,10 @@ Happy writing!
           pubDecls: ty[4],
           parent_container: ty[5],
         };
-      case 24: // Frame
-      case 25: // AnyFrame
-      case 26: // Vector
-      case 27: // EnumLiteral
+      case typeKinds.Frame:
+      case typeKinds.AnyFrame:
+      case typeKinds.Vector:
+      case typeKinds.EnumLiteral:
         return { kind: ty[0], name: ty[1] };
     }
   }
src/Autodoc.zig
@@ -766,15 +766,12 @@ const DocData = struct {
         array: []usize, // index in `exprs`
         call: usize, // index in `calls`
         enumLiteral: []const u8, // direct value
-        alignOf: usize, // index in `exprs`
         typeOf: usize, // index in `exprs`
-        typeInfo: usize, // index in `exprs`
         typeOf_peer: []usize,
         errorUnion: usize, // index in `types`
         as: As,
         sizeOf: usize, // index in `exprs`
         bitSizeOf: usize, // index in `exprs`
-        intFromEnum: usize, // index in `exprs`
         compileError: usize, // index in `exprs`
         optionalPayload: usize, // index in `exprs`
         elemVal: ElemVal,
@@ -794,9 +791,15 @@ const DocData = struct {
         mulAdd: MulAdd,
         switchIndex: usize, // index in `exprs`
         switchOp: SwitchOp,
+        unOp: UnOp,
+        unOpIndex: usize,
         binOp: BinOp,
         binOpIndex: usize,
         load: usize, // index in `exprs`
+        const UnOp = struct {
+            param: usize, // index in `exprs`
+            name: []const u8 = "", // tag name
+        };
         const BinOp = struct {
             lhs: usize, // index in `exprs`
             rhs: usize, // index in `exprs`
@@ -1671,8 +1674,7 @@ fn walkInstruction(
         .frame_type,
         .frame_size,
         .int_from_ptr,
-        .bit_not,
-        .bool_not,
+        .type_info,
         // @check
         .clz,
         .ctz,
@@ -1695,13 +1697,49 @@ fn walkInstruction(
             const param_index = self.exprs.items.len;
             try self.exprs.append(self.arena, param.expr);
 
-            self.exprs.items[bin_index] = .{ .builtin = .{ .name = @tagName(tags[inst_index]), .param = param_index } };
+            self.exprs.items[bin_index] = .{
+                .builtin = .{
+                    .name = @tagName(tags[inst_index]),
+                    .param = param_index,
+                },
+            };
 
             return DocData.WalkResult{
                 .typeRef = param.typeRef orelse .{ .type = @intFromEnum(Ref.type_type) },
                 .expr = .{ .builtinIndex = bin_index },
             };
         },
+        .bit_not,
+        .bool_not,
+        .negate_wrap,
+        => {
+            const un_node = data[inst_index].un_node;
+            const un_index = self.exprs.items.len;
+            try self.exprs.append(self.arena, .{ .unOp = .{ .param = 0 } });
+            const param = try self.walkRef(
+                file,
+                parent_scope,
+                parent_src,
+                un_node.operand,
+                false,
+                call_ctx,
+            );
+
+            const param_index = self.exprs.items.len;
+            try self.exprs.append(self.arena, param.expr);
+
+            self.exprs.items[un_index] = .{
+                .unOp = .{
+                    .name = @tagName(tags[inst_index]),
+                    .param = param_index,
+                },
+            };
+
+            return DocData.WalkResult{
+                .typeRef = param.typeRef,
+                .expr = .{ .unOpIndex = un_index },
+            };
+        },
         .bool_br_and, .bool_br_or => {
             const bool_br = data[inst_index].bool_br;
 
@@ -2407,12 +2445,20 @@ fn walkInstruction(
                 .int => |*int| int.negated = true,
                 .int_big => |*int_big| int_big.negated = true,
                 else => {
-                    printWithContext(
-                        file,
-                        inst_index,
-                        "TODO: support negation for more types",
-                        .{},
-                    );
+                    const un_index = self.exprs.items.len;
+                    try self.exprs.append(self.arena, .{ .unOp = .{ .param = 0 } });
+                    const param_index = self.exprs.items.len;
+                    try self.exprs.append(self.arena, operand.expr);
+                    self.exprs.items[un_index] = .{
+                        .unOp = .{
+                            .name = @tagName(tags[inst_index]),
+                            .param = param_index,
+                        },
+                    };
+                    return DocData.WalkResult{
+                        .typeRef = operand.typeRef,
+                        .expr = .{ .unOpIndex = un_index },
+                    };
                 },
             }
             return operand;
@@ -2466,12 +2512,20 @@ fn walkInstruction(
                 false,
                 call_ctx,
             );
+            const builtin_index = self.exprs.items.len;
+            try self.exprs.append(self.arena, .{ .builtin = .{ .param = 0 } });
             const operand_index = self.exprs.items.len;
             try self.exprs.append(self.arena, operand.expr);
+            self.exprs.items[builtin_index] = .{
+                .builtin = .{
+                    .name = @tagName(tags[inst_index]),
+                    .param = operand_index,
+                },
+            };
 
             return DocData.WalkResult{
                 .typeRef = .{ .type = @intFromEnum(Ref.comptime_int_type) },
-                .expr = .{ .intFromEnum = operand_index },
+                .expr = .{ .builtinIndex = builtin_index },
             };
         },
         .switch_block => {
@@ -2564,27 +2618,6 @@ fn walkInstruction(
                 .expr = .{ .typeOf = operand_index },
             };
         },
-        .type_info => {
-            // @check
-            const un_node = data[inst_index].un_node;
-
-            const operand = try self.walkRef(
-                file,
-                parent_scope,
-                parent_src,
-                un_node.operand,
-                need_type,
-                call_ctx,
-            );
-
-            const operand_index = self.exprs.items.len;
-            try self.exprs.append(self.arena, operand.expr);
-
-            return DocData.WalkResult{
-                .typeRef = operand.typeRef,
-                .expr = .{ .typeInfo = operand_index },
-            };
-        },
         .as_node, .as_shift_operand => {
             const pl_node = data[inst_index].pl_node;
             const extra = file.zir.extraData(Zir.Inst.As, pl_node.payload_index);