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;
}
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] };
}
}

View File

@ -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);