autodoc: Implement builtin function rendering.

Implement unary ops handling.
Fix getType in main.js
Minor cleanup of builtin function handling.
This commit is contained in:
Krzysztof Wolicki 2023-09-12 17:50:40 +02:00 committed by Loris Cro
parent 9a326b22d5
commit f2026e7dd6
2 changed files with 181 additions and 72 deletions

View File

@ -1522,6 +1522,47 @@ Happy writing!
return; 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": { case "binOpIndex": {
const binOp = zigAnalysis.exprs[expr.binOpIndex]; const binOp = zigAnalysis.exprs[expr.binOpIndex];
yield* ex(binOp, opts); yield* ex(binOp, opts);
@ -1669,6 +1710,52 @@ Happy writing!
return; 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": { case "builtinBinIndex": {
const builtinBinIndex = zigAnalysis.exprs[expr.builtinBinIndex]; const builtinBinIndex = zigAnalysis.exprs[expr.builtinBinIndex];
yield* ex(builtinBinIndex, opts); yield* ex(builtinBinIndex, opts);
@ -1899,15 +1986,6 @@ Happy writing!
return; 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": { case "switchIndex": {
const switchIndex = zigAnalysis.exprs[expr.switchIndex]; const switchIndex = zigAnalysis.exprs[expr.switchIndex];
yield* ex(switchIndex, opts); yield* ex(switchIndex, opts);
@ -4560,16 +4638,16 @@ Happy writing!
switch (ty[0]) { switch (ty[0]) {
default: default:
throw "unhandled type kind!"; throw "unhandled type kind!";
case 0: // Unanalyzed case typeKinds.Unanalyzed:
throw "unanalyzed type!"; throw "unanalyzed type!";
case 1: // Type case typeKinds.Type:
case 2: // Void case typeKinds.Void:
case 3: // Bool case typeKinds.Bool:
case 4: // NoReturn case typeKinds.NoReturn:
case 5: // Int case typeKinds.Int:
case 6: // Float case typeKinds.Float:
return { kind: ty[0], name: ty[1] }; return { kind: ty[0], name: ty[1] };
case 7: // Pointer case typeKinds.Pointer:
return { return {
kind: ty[0], kind: ty[0],
size: ty[1], size: ty[1],
@ -4588,14 +4666,14 @@ Happy writing!
has_addrspace: ty[14], has_addrspace: ty[14],
has_bit_range: ty[15], has_bit_range: ty[15],
}; };
case 8: // Array case typeKinds.Array:
return { return {
kind: ty[0], kind: ty[0],
len: ty[1], len: ty[1],
child: ty[2], child: ty[2],
sentinel: ty[3], sentinel: ty[3],
}; };
case 9: // Struct case typeKinds.Struct:
return { return {
kind: ty[0], kind: ty[0],
name: ty[1], name: ty[1],
@ -4610,36 +4688,36 @@ Happy writing!
parent_container: ty[10], parent_container: ty[10],
layout: ty[11], layout: ty[11],
}; };
case 10: // ComptimeExpr case typeKinds.ComptimeExpr:
case 11: // ComptimeFloat case typeKinds.ComptimeFloat:
case 12: // ComptimeInt case typeKinds.ComptimeInt:
case 13: // Undefined case typeKinds.Undefined:
case 14: // Null case typeKinds.Null:
return { kind: ty[0], name: ty[1] }; return { kind: ty[0], name: ty[1] };
case 15: // Optional case typeKinds.Optional:
return { return {
kind: ty[0], kind: ty[0],
name: ty[1], name: ty[1],
child: ty[2], child: ty[2],
}; };
case 16: // ErrorUnion case typeKinds.ErrorUnion:
return { return {
kind: ty[0], kind: ty[0],
lhs: ty[1], lhs: ty[1],
rhs: ty[2], rhs: ty[2],
}; };
case 17: // InferredErrorUnion case typeKinds.InferredErrorUnion:
return { return {
kind: ty[0], kind: ty[0],
payload: ty[1], payload: ty[1],
}; };
case 18: // ErrorSet case typeKinds.ErrorSet:
return { return {
kind: ty[0], kind: ty[0],
name: ty[1], name: ty[1],
fields: ty[2], fields: ty[2],
}; };
case 19: // Enum case typeKinds.Enum:
return { return {
kind: ty[0], kind: ty[0],
name: ty[1], name: ty[1],
@ -4651,7 +4729,7 @@ Happy writing!
nonexhaustive: ty[7], nonexhaustive: ty[7],
parent_container: ty[8], parent_container: ty[8],
}; };
case 20: // Union case typeKinds.Union:
return { return {
kind: ty[0], kind: ty[0],
name: ty[1], name: ty[1],
@ -4664,7 +4742,7 @@ Happy writing!
parent_container: ty[8], parent_container: ty[8],
layout: ty[9], layout: ty[9],
}; };
case 21: // Fn case typeKinds.Fn:
return { return {
kind: ty[0], kind: ty[0],
name: ty[1], name: ty[1],
@ -4683,9 +4761,7 @@ Happy writing!
is_test: ty[14], is_test: ty[14],
is_extern: ty[15], is_extern: ty[15],
}; };
case 22: // BoundFn case typeKinds.Opaque:
return { kind: ty[0], name: ty[1] };
case 23: // Opaque
return { return {
kind: ty[0], kind: ty[0],
name: ty[1], name: ty[1],
@ -4694,10 +4770,10 @@ Happy writing!
pubDecls: ty[4], pubDecls: ty[4],
parent_container: ty[5], parent_container: ty[5],
}; };
case 24: // Frame case typeKinds.Frame:
case 25: // AnyFrame case typeKinds.AnyFrame:
case 26: // Vector case typeKinds.Vector:
case 27: // EnumLiteral case typeKinds.EnumLiteral:
return { kind: ty[0], name: ty[1] }; return { kind: ty[0], name: ty[1] };
} }
} }

View File

@ -766,15 +766,12 @@ const DocData = struct {
array: []usize, // index in `exprs` array: []usize, // index in `exprs`
call: usize, // index in `calls` call: usize, // index in `calls`
enumLiteral: []const u8, // direct value enumLiteral: []const u8, // direct value
alignOf: usize, // index in `exprs`
typeOf: usize, // index in `exprs` typeOf: usize, // index in `exprs`
typeInfo: usize, // index in `exprs`
typeOf_peer: []usize, typeOf_peer: []usize,
errorUnion: usize, // index in `types` errorUnion: usize, // index in `types`
as: As, as: As,
sizeOf: usize, // index in `exprs` sizeOf: usize, // index in `exprs`
bitSizeOf: usize, // index in `exprs` bitSizeOf: usize, // index in `exprs`
intFromEnum: usize, // index in `exprs`
compileError: usize, // index in `exprs` compileError: usize, // index in `exprs`
optionalPayload: usize, // index in `exprs` optionalPayload: usize, // index in `exprs`
elemVal: ElemVal, elemVal: ElemVal,
@ -794,9 +791,15 @@ const DocData = struct {
mulAdd: MulAdd, mulAdd: MulAdd,
switchIndex: usize, // index in `exprs` switchIndex: usize, // index in `exprs`
switchOp: SwitchOp, switchOp: SwitchOp,
unOp: UnOp,
unOpIndex: usize,
binOp: BinOp, binOp: BinOp,
binOpIndex: usize, binOpIndex: usize,
load: usize, // index in `exprs` load: usize, // index in `exprs`
const UnOp = struct {
param: usize, // index in `exprs`
name: []const u8 = "", // tag name
};
const BinOp = struct { const BinOp = struct {
lhs: usize, // index in `exprs` lhs: usize, // index in `exprs`
rhs: usize, // index in `exprs` rhs: usize, // index in `exprs`
@ -1671,8 +1674,7 @@ fn walkInstruction(
.frame_type, .frame_type,
.frame_size, .frame_size,
.int_from_ptr, .int_from_ptr,
.bit_not, .type_info,
.bool_not,
// @check // @check
.clz, .clz,
.ctz, .ctz,
@ -1695,13 +1697,49 @@ fn walkInstruction(
const param_index = self.exprs.items.len; const param_index = self.exprs.items.len;
try self.exprs.append(self.arena, param.expr); 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{ return DocData.WalkResult{
.typeRef = param.typeRef orelse .{ .type = @intFromEnum(Ref.type_type) }, .typeRef = param.typeRef orelse .{ .type = @intFromEnum(Ref.type_type) },
.expr = .{ .builtinIndex = bin_index }, .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 => { .bool_br_and, .bool_br_or => {
const bool_br = data[inst_index].bool_br; const bool_br = data[inst_index].bool_br;
@ -2407,12 +2445,20 @@ fn walkInstruction(
.int => |*int| int.negated = true, .int => |*int| int.negated = true,
.int_big => |*int_big| int_big.negated = true, .int_big => |*int_big| int_big.negated = true,
else => { else => {
printWithContext( const un_index = self.exprs.items.len;
file, try self.exprs.append(self.arena, .{ .unOp = .{ .param = 0 } });
inst_index, const param_index = self.exprs.items.len;
"TODO: support negation for more types", 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; return operand;
@ -2466,12 +2512,20 @@ fn walkInstruction(
false, false,
call_ctx, 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; const operand_index = self.exprs.items.len;
try self.exprs.append(self.arena, operand.expr); 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{ return DocData.WalkResult{
.typeRef = .{ .type = @intFromEnum(Ref.comptime_int_type) }, .typeRef = .{ .type = @intFromEnum(Ref.comptime_int_type) },
.expr = .{ .intFromEnum = operand_index }, .expr = .{ .builtinIndex = builtin_index },
}; };
}, },
.switch_block => { .switch_block => {
@ -2564,27 +2618,6 @@ fn walkInstruction(
.expr = .{ .typeOf = operand_index }, .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 => { .as_node, .as_shift_operand => {
const pl_node = data[inst_index].pl_node; const pl_node = data[inst_index].pl_node;
const extra = file.zir.extraData(Zir.Inst.As, pl_node.payload_index); const extra = file.zir.extraData(Zir.Inst.As, pl_node.payload_index);