authorgravatar for der.teufel.mail@gmail.comKrzysztof Wolicki <der.teufel.mail@gmail.com> 2023-09-12 17:50:40+02:00
committergravatar for kappaloris@gmail.comLoris Cro <kappaloris@gmail.com> 2023-09-16 17:35:11+02:00
logf2026e7dd650e07defeefc9913f6fb08f9b45c21
treedef1bb547586b07889044de3a5c5782ddeb849f0
parent9a326b22d58a81a6d2b02c9f1c4be82244cfc89a

autodoc: Implement builtin function rendering.

Implement unary ops handling. Fix getType in main.js Minor cleanup of builtin function handling.

2 files changed, 181 insertions(+), 72 deletions(-)

lib/docs/main.js+114-38
...@@ -1522,6 +1522,47 @@ Happy writing!...@@ -1522,6 +1522,47 @@ Happy writing!
1522 return;1522 return;
1523 }1523 }
15241524
1525 case "unOpIndex": {
1526 const unOp = zigAnalysis.exprs[expr.unOpIndex];
1527 yield* ex(unOp, opts);
1528 return;
1529 }
1530
1531 case "unOp": {
1532 const param = zigAnalysis.exprs[expr.unOp.param];
1533
1534 switch (expr.unOp.name) {
1535 case "bit_not": {
1536 yield { src: "~", tag: Tag.tilde };
1537 break;
1538 }
1539 case "bool_not": {
1540 yield { src: "!", tag: Tag.bang };
1541 break;
1542 }
1543 case "negate_wrap": {
1544 yield { src: "-%", tag: Tag.minus_percent };
1545 break;
1546 }
1547 case "negate": {
1548 yield { src: "-", tag: Tag.minus };
1549 break;
1550 }
1551 default:
1552 throw "unOp: `" + expr.unOp.name + "` not implemented yet!"
1553 }
1554
1555 if (param["binOpIndex"] !== undefined) {
1556 yield Tok.l_paren;
1557 yield* ex(param, opts);
1558 yield Tok.r_paren;
1559 } else {
1560 yield* ex(param, opts);
1561 }
1562
1563 return;
1564 }
1565
1525 case "binOpIndex": {1566 case "binOpIndex": {
1526 const binOp = zigAnalysis.exprs[expr.binOpIndex];1567 const binOp = zigAnalysis.exprs[expr.binOpIndex];
1527 yield* ex(binOp, opts);1568 yield* ex(binOp, opts);
...@@ -1669,6 +1710,52 @@ Happy writing!...@@ -1669,6 +1710,52 @@ Happy writing!
1669 return;1710 return;
1670 }1711 }
16711712
1713 case "builtin": {
1714 const builtin = expr.builtin;
1715 let name = "@";
1716 const param = zigAnalysis.exprs[builtin.param];
1717 switch (builtin.name) {
1718 case "align_of": { name += "alignOf"; break; }
1719 case "int_from_bool": { name += "intFromBool"; break; }
1720 case "embed_file": { name += "embedFile"; break; }
1721 case "error_name": { name += "errorName"; break; }
1722 case "panic": { name += "panic"; break; }
1723 case "set_runtime_safety": { name += "setRuntimeSafety"; break; }
1724 case "sqrt": { name += "sqrt"; break; }
1725 case "sin": { name += "sin"; break; }
1726 case "cos": { name += "cos"; break; }
1727 case "tan": { name += "tan"; break; }
1728 case "exp": { name += "exp"; break; }
1729 case "exp2": { name += "exp2"; break; }
1730 case "log": { name += "log"; break; }
1731 case "log2": { name += "log2"; break; }
1732 case "log10": { name += "log10"; break; }
1733 case "fabs": { name += "fabs"; break; }
1734 case "floor": { name += "floor"; break; }
1735 case "ceil": { name += "ceil"; break; }
1736 case "trunc": { name += "trunc"; break; }
1737 case "round": { name += "round"; break; }
1738 case "tag_name": { name += "tagName"; break; }
1739 case "type_name": { name += "typeName"; break; }
1740 case "type_info": { name += "typeInfo"; break; }
1741 case "frame_type": { name += "Frame"; break; }
1742 case "frame_size": { name += "frameSize"; break; }
1743 case "int_from_ptr": { name += "intFromPtr"; break; }
1744 case "int_from_enum": { name += "intFromEnum"; break; }
1745 case "clz": { name += "clz"; break; }
1746 case "ctz": { name += "ctz"; break; }
1747 case "pop_count": { name += "popCount"; break; }
1748 case "byte_swap": { name += "byteSwap"; break; }
1749 case "bit_reverse": { name += "bitReverse"; break; }
1750 default: throw "builtin: `" + builtin.name + "` not implemented yet!";
1751 }
1752 yield { src: name, tag: Tag.builtin };
1753 yield Tok.l_paren;
1754 yield* ex(param, opts);
1755 yield Tok.r_paren;
1756 return;
1757 }
1758
1672 case "builtinBinIndex": {1759 case "builtinBinIndex": {
1673 const builtinBinIndex = zigAnalysis.exprs[expr.builtinBinIndex];1760 const builtinBinIndex = zigAnalysis.exprs[expr.builtinBinIndex];
1674 yield* ex(builtinBinIndex, opts);1761 yield* ex(builtinBinIndex, opts);
...@@ -1899,15 +1986,6 @@ Happy writing!...@@ -1899,15 +1986,6 @@ Happy writing!
1899 return;1986 return;
1900 }1987 }
19011988
1902 case "typeInfo": {
1903 const arg = zigAnalysis.exprs[expr.typeInfo];
1904 yield { src: "@typeInfo", tag: Tag.builtin };
1905 yield Tok.l_paren;
1906 yield* ex(arg, opts);
1907 yield Tok.r_paren;
1908 return;
1909 }
1910
1911 case "switchIndex": {1989 case "switchIndex": {
1912 const switchIndex = zigAnalysis.exprs[expr.switchIndex];1990 const switchIndex = zigAnalysis.exprs[expr.switchIndex];
1913 yield* ex(switchIndex, opts);1991 yield* ex(switchIndex, opts);
...@@ -4560,16 +4638,16 @@ Happy writing!...@@ -4560,16 +4638,16 @@ Happy writing!
4560 switch (ty[0]) {4638 switch (ty[0]) {
4561 default:4639 default:
4562 throw "unhandled type kind!";4640 throw "unhandled type kind!";
4563 case 0: // Unanalyzed4641 case typeKinds.Unanalyzed:
4564 throw "unanalyzed type!";4642 throw "unanalyzed type!";
4565 case 1: // Type4643 case typeKinds.Type:
4566 case 2: // Void 4644 case typeKinds.Void:
4567 case 3: // Bool4645 case typeKinds.Bool:
4568 case 4: // NoReturn4646 case typeKinds.NoReturn:
4569 case 5: // Int4647 case typeKinds.Int:
4570 case 6: // Float4648 case typeKinds.Float:
4571 return { kind: ty[0], name: ty[1] };4649 return { kind: ty[0], name: ty[1] };
4572 case 7: // Pointer4650 case typeKinds.Pointer:
4573 return {4651 return {
4574 kind: ty[0],4652 kind: ty[0],
4575 size: ty[1],4653 size: ty[1],
...@@ -4588,14 +4666,14 @@ Happy writing!...@@ -4588,14 +4666,14 @@ Happy writing!
4588 has_addrspace: ty[14],4666 has_addrspace: ty[14],
4589 has_bit_range: ty[15],4667 has_bit_range: ty[15],
4590 };4668 };
4591 case 8: // Array4669 case typeKinds.Array:
4592 return {4670 return {
4593 kind: ty[0],4671 kind: ty[0],
4594 len: ty[1],4672 len: ty[1],
4595 child: ty[2],4673 child: ty[2],
4596 sentinel: ty[3],4674 sentinel: ty[3],
4597 };4675 };
4598 case 9: // Struct4676 case typeKinds.Struct:
4599 return {4677 return {
4600 kind: ty[0],4678 kind: ty[0],
4601 name: ty[1],4679 name: ty[1],
...@@ -4610,36 +4688,36 @@ Happy writing!...@@ -4610,36 +4688,36 @@ Happy writing!
4610 parent_container: ty[10],4688 parent_container: ty[10],
4611 layout: ty[11],4689 layout: ty[11],
4612 };4690 };
4613 case 10: // ComptimeExpr4691 case typeKinds.ComptimeExpr:
4614 case 11: // ComptimeFloat4692 case typeKinds.ComptimeFloat:
4615 case 12: // ComptimeInt4693 case typeKinds.ComptimeInt:
4616 case 13: // Undefined4694 case typeKinds.Undefined:
4617 case 14: // Null4695 case typeKinds.Null:
4618 return { kind: ty[0], name: ty[1] };4696 return { kind: ty[0], name: ty[1] };
4619 case 15: // Optional4697 case typeKinds.Optional:
4620 return {4698 return {
4621 kind: ty[0],4699 kind: ty[0],
4622 name: ty[1],4700 name: ty[1],
4623 child: ty[2],4701 child: ty[2],
4624 };4702 };
4625 case 16: // ErrorUnion4703 case typeKinds.ErrorUnion:
4626 return {4704 return {
4627 kind: ty[0],4705 kind: ty[0],
4628 lhs: ty[1],4706 lhs: ty[1],
4629 rhs: ty[2],4707 rhs: ty[2],
4630 };4708 };
4631 case 17: // InferredErrorUnion4709 case typeKinds.InferredErrorUnion:
4632 return {4710 return {
4633 kind: ty[0],4711 kind: ty[0],
4634 payload: ty[1],4712 payload: ty[1],
4635 };4713 };
4636 case 18: // ErrorSet4714 case typeKinds.ErrorSet:
4637 return {4715 return {
4638 kind: ty[0],4716 kind: ty[0],
4639 name: ty[1],4717 name: ty[1],
4640 fields: ty[2],4718 fields: ty[2],
4641 };4719 };
4642 case 19: // Enum4720 case typeKinds.Enum:
4643 return {4721 return {
4644 kind: ty[0],4722 kind: ty[0],
4645 name: ty[1],4723 name: ty[1],
...@@ -4651,7 +4729,7 @@ Happy writing!...@@ -4651,7 +4729,7 @@ Happy writing!
4651 nonexhaustive: ty[7],4729 nonexhaustive: ty[7],
4652 parent_container: ty[8],4730 parent_container: ty[8],
4653 };4731 };
4654 case 20: // Union4732 case typeKinds.Union:
4655 return {4733 return {
4656 kind: ty[0],4734 kind: ty[0],
4657 name: ty[1],4735 name: ty[1],
...@@ -4664,7 +4742,7 @@ Happy writing!...@@ -4664,7 +4742,7 @@ Happy writing!
4664 parent_container: ty[8],4742 parent_container: ty[8],
4665 layout: ty[9],4743 layout: ty[9],
4666 };4744 };
4667 case 21: // Fn4745 case typeKinds.Fn:
4668 return {4746 return {
4669 kind: ty[0],4747 kind: ty[0],
4670 name: ty[1],4748 name: ty[1],
...@@ -4683,9 +4761,7 @@ Happy writing!...@@ -4683,9 +4761,7 @@ Happy writing!
4683 is_test: ty[14],4761 is_test: ty[14],
4684 is_extern: ty[15],4762 is_extern: ty[15],
4685 };4763 };
4686 case 22: // BoundFn4764 case typeKinds.Opaque:
4687 return { kind: ty[0], name: ty[1] };
4688 case 23: // Opaque
4689 return {4765 return {
4690 kind: ty[0],4766 kind: ty[0],
4691 name: ty[1],4767 name: ty[1],
...@@ -4694,10 +4770,10 @@ Happy writing!...@@ -4694,10 +4770,10 @@ Happy writing!
4694 pubDecls: ty[4],4770 pubDecls: ty[4],
4695 parent_container: ty[5],4771 parent_container: ty[5],
4696 };4772 };
4697 case 24: // Frame4773 case typeKinds.Frame:
4698 case 25: // AnyFrame4774 case typeKinds.AnyFrame:
4699 case 26: // Vector4775 case typeKinds.Vector:
4700 case 27: // EnumLiteral4776 case typeKinds.EnumLiteral:
4701 return { kind: ty[0], name: ty[1] };4777 return { kind: ty[0], name: ty[1] };
4702 }4778 }
4703 }4779 }
src/Autodoc.zig+67-34
...@@ -766,15 +766,12 @@ const DocData = struct {...@@ -766,15 +766,12 @@ const DocData = struct {
766 array: []usize, // index in `exprs`766 array: []usize, // index in `exprs`
767 call: usize, // index in `calls`767 call: usize, // index in `calls`
768 enumLiteral: []const u8, // direct value768 enumLiteral: []const u8, // direct value
769 alignOf: usize, // index in `exprs`
770 typeOf: usize, // index in `exprs`769 typeOf: usize, // index in `exprs`
771 typeInfo: usize, // index in `exprs`
772 typeOf_peer: []usize,770 typeOf_peer: []usize,
773 errorUnion: usize, // index in `types`771 errorUnion: usize, // index in `types`
774 as: As,772 as: As,
775 sizeOf: usize, // index in `exprs`773 sizeOf: usize, // index in `exprs`
776 bitSizeOf: usize, // index in `exprs`774 bitSizeOf: usize, // index in `exprs`
777 intFromEnum: usize, // index in `exprs`
778 compileError: usize, // index in `exprs`775 compileError: usize, // index in `exprs`
779 optionalPayload: usize, // index in `exprs`776 optionalPayload: usize, // index in `exprs`
780 elemVal: ElemVal,777 elemVal: ElemVal,
...@@ -794,9 +791,15 @@ const DocData = struct {...@@ -794,9 +791,15 @@ const DocData = struct {
794 mulAdd: MulAdd,791 mulAdd: MulAdd,
795 switchIndex: usize, // index in `exprs`792 switchIndex: usize, // index in `exprs`
796 switchOp: SwitchOp,793 switchOp: SwitchOp,
794 unOp: UnOp,
795 unOpIndex: usize,
797 binOp: BinOp,796 binOp: BinOp,
798 binOpIndex: usize,797 binOpIndex: usize,
799 load: usize, // index in `exprs`798 load: usize, // index in `exprs`
799 const UnOp = struct {
800 param: usize, // index in `exprs`
801 name: []const u8 = "", // tag name
802 };
800 const BinOp = struct {803 const BinOp = struct {
801 lhs: usize, // index in `exprs`804 lhs: usize, // index in `exprs`
802 rhs: usize, // index in `exprs`805 rhs: usize, // index in `exprs`
...@@ -1671,8 +1674,7 @@ fn walkInstruction(...@@ -1671,8 +1674,7 @@ fn walkInstruction(
1671 .frame_type,1674 .frame_type,
1672 .frame_size,1675 .frame_size,
1673 .int_from_ptr,1676 .int_from_ptr,
1674 .bit_not,1677 .type_info,
1675 .bool_not,
1676 // @check1678 // @check
1677 .clz,1679 .clz,
1678 .ctz,1680 .ctz,
...@@ -1695,13 +1697,49 @@ fn walkInstruction(...@@ -1695,13 +1697,49 @@ fn walkInstruction(
1695 const param_index = self.exprs.items.len;1697 const param_index = self.exprs.items.len;
1696 try self.exprs.append(self.arena, param.expr);1698 try self.exprs.append(self.arena, param.expr);
16971699
1698 self.exprs.items[bin_index] = .{ .builtin = .{ .name = @tagName(tags[inst_index]), .param = param_index } };1700 self.exprs.items[bin_index] = .{
1701 .builtin = .{
1702 .name = @tagName(tags[inst_index]),
1703 .param = param_index,
1704 },
1705 };
16991706
1700 return DocData.WalkResult{1707 return DocData.WalkResult{
1701 .typeRef = param.typeRef orelse .{ .type = @intFromEnum(Ref.type_type) },1708 .typeRef = param.typeRef orelse .{ .type = @intFromEnum(Ref.type_type) },
1702 .expr = .{ .builtinIndex = bin_index },1709 .expr = .{ .builtinIndex = bin_index },
1703 };1710 };
1704 },1711 },
1712 .bit_not,
1713 .bool_not,
1714 .negate_wrap,
1715 => {
1716 const un_node = data[inst_index].un_node;
1717 const un_index = self.exprs.items.len;
1718 try self.exprs.append(self.arena, .{ .unOp = .{ .param = 0 } });
1719 const param = try self.walkRef(
1720 file,
1721 parent_scope,
1722 parent_src,
1723 un_node.operand,
1724 false,
1725 call_ctx,
1726 );
1727
1728 const param_index = self.exprs.items.len;
1729 try self.exprs.append(self.arena, param.expr);
1730
1731 self.exprs.items[un_index] = .{
1732 .unOp = .{
1733 .name = @tagName(tags[inst_index]),
1734 .param = param_index,
1735 },
1736 };
1737
1738 return DocData.WalkResult{
1739 .typeRef = param.typeRef,
1740 .expr = .{ .unOpIndex = un_index },
1741 };
1742 },
1705 .bool_br_and, .bool_br_or => {1743 .bool_br_and, .bool_br_or => {
1706 const bool_br = data[inst_index].bool_br;1744 const bool_br = data[inst_index].bool_br;
17071745
...@@ -2407,12 +2445,20 @@ fn walkInstruction(...@@ -2407,12 +2445,20 @@ fn walkInstruction(
2407 .int => |*int| int.negated = true,2445 .int => |*int| int.negated = true,
2408 .int_big => |*int_big| int_big.negated = true,2446 .int_big => |*int_big| int_big.negated = true,
2409 else => {2447 else => {
2410 printWithContext(2448 const un_index = self.exprs.items.len;
2411 file,2449 try self.exprs.append(self.arena, .{ .unOp = .{ .param = 0 } });
2412 inst_index,2450 const param_index = self.exprs.items.len;
2413 "TODO: support negation for more types",2451 try self.exprs.append(self.arena, operand.expr);
2414 .{},2452 self.exprs.items[un_index] = .{
2415 );2453 .unOp = .{
2454 .name = @tagName(tags[inst_index]),
2455 .param = param_index,
2456 },
2457 };
2458 return DocData.WalkResult{
2459 .typeRef = operand.typeRef,
2460 .expr = .{ .unOpIndex = un_index },
2461 };
2416 },2462 },
2417 }2463 }
2418 return operand;2464 return operand;
...@@ -2466,12 +2512,20 @@ fn walkInstruction(...@@ -2466,12 +2512,20 @@ fn walkInstruction(
2466 false,2512 false,
2467 call_ctx,2513 call_ctx,
2468 );2514 );
2515 const builtin_index = self.exprs.items.len;
2516 try self.exprs.append(self.arena, .{ .builtin = .{ .param = 0 } });
2469 const operand_index = self.exprs.items.len;2517 const operand_index = self.exprs.items.len;
2470 try self.exprs.append(self.arena, operand.expr);2518 try self.exprs.append(self.arena, operand.expr);
2519 self.exprs.items[builtin_index] = .{
2520 .builtin = .{
2521 .name = @tagName(tags[inst_index]),
2522 .param = operand_index,
2523 },
2524 };
24712525
2472 return DocData.WalkResult{2526 return DocData.WalkResult{
2473 .typeRef = .{ .type = @intFromEnum(Ref.comptime_int_type) },2527 .typeRef = .{ .type = @intFromEnum(Ref.comptime_int_type) },
2474 .expr = .{ .intFromEnum = operand_index },2528 .expr = .{ .builtinIndex = builtin_index },
2475 };2529 };
2476 },2530 },
2477 .switch_block => {2531 .switch_block => {
...@@ -2564,27 +2618,6 @@ fn walkInstruction(...@@ -2564,27 +2618,6 @@ fn walkInstruction(
2564 .expr = .{ .typeOf = operand_index },2618 .expr = .{ .typeOf = operand_index },
2565 };2619 };
2566 },2620 },
2567 .type_info => {
2568 // @check
2569 const un_node = data[inst_index].un_node;
2570
2571 const operand = try self.walkRef(
2572 file,
2573 parent_scope,
2574 parent_src,
2575 un_node.operand,
2576 need_type,
2577 call_ctx,
2578 );
2579
2580 const operand_index = self.exprs.items.len;
2581 try self.exprs.append(self.arena, operand.expr);
2582
2583 return DocData.WalkResult{
2584 .typeRef = operand.typeRef,
2585 .expr = .{ .typeInfo = operand_index },
2586 };
2587 },
2588 .as_node, .as_shift_operand => {2621 .as_node, .as_shift_operand => {
2589 const pl_node = data[inst_index].pl_node;2622 const pl_node = data[inst_index].pl_node;
2590 const extra = file.zir.extraData(Zir.Inst.As, pl_node.payload_index);2623 const extra = file.zir.extraData(Zir.Inst.As, pl_node.payload_index);