Commit 555028086a

Krzysztof Wolicki <der.teufel.mail@gmail.com>
2023-09-03 17:20:23
autodoc: Implement `@call`, `@unionInit`, `@mulAdd` support (#16918)
* autodoc: Implement `@call`, `@unionInit`, `@mulAdd` support * autodoc: Implement builtinIndex in ex
1 parent 86a9e1d
Changed files (2)
lib
docs
src
lib/docs/main.js
@@ -1437,7 +1437,9 @@ Happy writing!
       }
 
       case "float": {
-        yield { src: expr.float, tag: Tag.number_literal };
+        let float = expr.float;
+        if (Number.isSafeInteger(float)) float = float.toFixed(1);
+        yield { src: float, tag: Tag.number_literal };
         return;
       }
 
@@ -1495,7 +1497,7 @@ Happy writing!
       case "struct": {
         yield Tok.period;
         yield Tok.l_brace;
-        yield Tok.space;
+        if (expr.struct.length > 0) yield Tok.space;
 
         for (let i = 0; i < expr.struct.length; i++) {
           const fv = expr.struct[i];
@@ -1579,6 +1581,10 @@ Happy writing!
             yield { src: "/", tag: Tag.slash };
             break;
           }
+          case "xor": {
+            yield { src: "^", tag: Tag.caret };
+            break;
+          }
           case "shl": {
             yield { src: "<<", tag: Tag.angle_bracket_angle_bracket_left };
             break;
@@ -1655,6 +1661,12 @@ Happy writing!
         return;
       }
 
+      case "builtinIndex": {
+        const builtin = zigAnalysis.exprs[expr.builtinIndex];
+        yield* ex(builtin, opts);
+        return;
+      }
+
       case "builtinBinIndex": {
         const builtinBinIndex = zigAnalysis.exprs[expr.builtinBinIndex];
         yield* ex(builtinBinIndex, opts);
@@ -1793,6 +1805,64 @@ Happy writing!
         return;
       }
 
+      case "unionInit": {
+        let ui = expr.unionInit;
+        let type = zigAnalysis.exprs[ui.type];
+        let field = zigAnalysis.exprs[ui.field];
+        let init = zigAnalysis.exprs[ui.init];
+        yield { src: "@unionInit", tag: Tag.builtin };
+        yield Tok.l_paren;
+        yield* ex(type, opts);
+        yield Tok.comma;
+        yield Tok.space;
+        yield* ex(field, opts);
+        yield Tok.comma;
+        yield Tok.space;
+        yield* ex(init, opts);
+        yield Tok.r_paren;
+        return;
+      }
+
+      case "builtinCall": {
+        let bcall = expr.builtinCall;
+        let mods = zigAnalysis.exprs[bcall.modifier];
+        let calee = zigAnalysis.exprs[bcall.function];
+        let args = zigAnalysis.exprs[bcall.args];
+        yield { src: "@call", tag: Tag.builtin };
+        yield Tok.l_paren;
+        yield* ex(mods, opts);
+        yield Tok.comma;
+        yield Tok.space;
+        yield* ex(calee, opts);
+        yield Tok.comma;
+        yield Tok.space;
+        yield* ex(args, opts);
+        yield Tok.r_paren;
+        return;
+      }
+
+      case "mulAdd": {
+        let muladd = expr.mulAdd;
+        let mul1 = zigAnalysis.exprs[muladd.mulend1];
+        let mul2 = zigAnalysis.exprs[muladd.mulend2];
+        let add = zigAnalysis.exprs[muladd.addend];
+        let type = zigAnalysis.exprs[muladd.type];
+        yield { src: "@mulAdd", tag: Tag.builtin };
+        yield Tok.l_paren;
+        yield* ex(type, opts);
+        yield Tok.comma;
+        yield Tok.space;
+        yield* ex(mul1, opts);
+        yield Tok.comma;
+        yield Tok.space;
+        yield* ex(mul2, opts);
+        yield Tok.comma;
+        yield Tok.space;
+        yield* ex(add, opts);
+        yield Tok.r_paren;
+        return;
+      }
+
       case "enumLiteral": {
         let literal = expr.enumLiteral;
         yield Tok.period;
src/Autodoc.zig
@@ -789,6 +789,9 @@ const DocData = struct {
         builtinIndex: usize,
         builtinBin: BuiltinBin,
         builtinBinIndex: usize,
+        unionInit: UnionInit,
+        builtinCall: BuiltinCall,
+        mulAdd: MulAdd,
         switchIndex: usize, // index in `exprs`
         switchOp: SwitchOp,
         binOp: BinOp,
@@ -810,10 +813,26 @@ const DocData = struct {
             lhs: usize, // index in `exprs`
             rhs: usize, // index in `exprs`
         };
+        const UnionInit = struct {
+            type: usize, // index in `exprs`
+            field: usize, // index in `exprs`
+            init: usize, // index in `exprs`
+        };
         const Builtin = struct {
             name: []const u8 = "", // fn name
             param: usize, // index in `exprs`
         };
+        const BuiltinCall = struct {
+            modifier: usize, // index in `exprs`
+            function: usize, // index in `exprs`
+            args: usize, // index in `exprs`
+        };
+        const MulAdd = struct {
+            mulend1: usize, // index in `exprs`
+            mulend2: usize, // index in `exprs`
+            addend: usize, // index in `exprs`
+            type: usize, // index in `exprs`
+        };
         const Slice = struct {
             lhs: usize, // index in `exprs`
             start: usize,
@@ -1519,6 +1538,7 @@ fn walkInstruction(
         .shr,
         .bit_or,
         .bit_and,
+        .xor,
         // @check still not working when applied in std
         // .array_cat,
         // .array_mul,
@@ -1798,6 +1818,152 @@ fn walkInstruction(
                 .expr = .{ .builtinBinIndex = binop_index },
             };
         },
+        .mul_add => {
+            const pl_node = data[inst_index].pl_node;
+            const extra = file.zir.extraData(Zir.Inst.MulAdd, pl_node.payload_index);
+
+            var mul1: DocData.WalkResult = try self.walkRef(
+                file,
+                parent_scope,
+                parent_src,
+                extra.data.mulend1,
+                false,
+                call_ctx,
+            );
+            var mul2: DocData.WalkResult = try self.walkRef(
+                file,
+                parent_scope,
+                parent_src,
+                extra.data.mulend2,
+                false,
+                call_ctx,
+            );
+            var add: DocData.WalkResult = try self.walkRef(
+                file,
+                parent_scope,
+                parent_src,
+                extra.data.addend,
+                false,
+                call_ctx,
+            );
+
+            const mul1_index = self.exprs.items.len;
+            try self.exprs.append(self.arena, mul1.expr);
+            const mul2_index = self.exprs.items.len;
+            try self.exprs.append(self.arena, mul2.expr);
+            const add_index = self.exprs.items.len;
+            try self.exprs.append(self.arena, add.expr);
+
+            var type_index: usize = self.exprs.items.len;
+            try self.exprs.append(self.arena, add.typeRef orelse .{ .type = @intFromEnum(Ref.type_type) });
+
+            return DocData.WalkResult{
+                .typeRef = add.typeRef,
+                .expr = .{
+                    .mulAdd = .{
+                        .mulend1 = mul1_index,
+                        .mulend2 = mul2_index,
+                        .addend = add_index,
+                        .type = type_index,
+                    },
+                },
+            };
+        },
+        .union_init => {
+            const pl_node = data[inst_index].pl_node;
+            const extra = file.zir.extraData(Zir.Inst.UnionInit, pl_node.payload_index);
+
+            var union_type: DocData.WalkResult = try self.walkRef(
+                file,
+                parent_scope,
+                parent_src,
+                extra.data.union_type,
+                false,
+                call_ctx,
+            );
+            var field_name: DocData.WalkResult = try self.walkRef(
+                file,
+                parent_scope,
+                parent_src,
+                extra.data.field_name,
+                false,
+                call_ctx,
+            );
+            var init: DocData.WalkResult = try self.walkRef(
+                file,
+                parent_scope,
+                parent_src,
+                extra.data.init,
+                false,
+                call_ctx,
+            );
+
+            const union_type_index = self.exprs.items.len;
+            try self.exprs.append(self.arena, union_type.expr);
+            const field_name_index = self.exprs.items.len;
+            try self.exprs.append(self.arena, field_name.expr);
+            const init_index = self.exprs.items.len;
+            try self.exprs.append(self.arena, init.expr);
+
+            return DocData.WalkResult{
+                .typeRef = union_type.expr,
+                .expr = .{
+                    .unionInit = .{
+                        .type = union_type_index,
+                        .field = field_name_index,
+                        .init = init_index,
+                    },
+                },
+            };
+        },
+        .builtin_call => {
+            const pl_node = data[inst_index].pl_node;
+            const extra = file.zir.extraData(Zir.Inst.BuiltinCall, pl_node.payload_index);
+
+            var modifier: DocData.WalkResult = try self.walkRef(
+                file,
+                parent_scope,
+                parent_src,
+                extra.data.modifier,
+                false,
+                call_ctx,
+            );
+
+            var callee: DocData.WalkResult = try self.walkRef(
+                file,
+                parent_scope,
+                parent_src,
+                extra.data.callee,
+                false,
+                call_ctx,
+            );
+
+            var args: DocData.WalkResult = try self.walkRef(
+                file,
+                parent_scope,
+                parent_src,
+                extra.data.args,
+                false,
+                call_ctx,
+            );
+
+            const modifier_index = self.exprs.items.len;
+            try self.exprs.append(self.arena, modifier.expr);
+            const function_index = self.exprs.items.len;
+            try self.exprs.append(self.arena, callee.expr);
+            const args_index = self.exprs.items.len;
+            try self.exprs.append(self.arena, args.expr);
+
+            return DocData.WalkResult{
+                .expr = .{
+                    .builtinCall = .{
+                        .modifier = modifier_index,
+                        .function = function_index,
+                        .args = args_index,
+                    },
+                },
+            };
+        },
         .error_union_type => {
             const pl_node = data[inst_index].pl_node;
             const extra = file.zir.extraData(Zir.Inst.Bin, pl_node.payload_index);