From f04f23a3aaeb0e0b3b17395fdc7ee0742a3f983e Mon Sep 17 00:00:00 2001 From: Vallahor Date: Sat, 28 May 2022 00:34:35 -0300 Subject: [PATCH] add: extern, callconv and return errors --- lib/docs/main.js | 58 +++++++++++++++---------------- src/Autodoc.zig | 88 +++++++++++++++++++++++++++++++++++++++++------- 2 files changed, 105 insertions(+), 41 deletions(-) diff --git a/lib/docs/main.js b/lib/docs/main.js index 4bc867d297..167642a3f6 100644 --- a/lib/docs/main.js +++ b/lib/docs/main.js @@ -1062,6 +1062,13 @@ var zigAnalysis; function exprName(expr, opts) { switch (Object.keys(expr)[0]) { default: throw "oh no"; + case "errorUnion": { + const errUnionObj = zigAnalysis.types[expr.errorUnion]; + let lhs = exprName(errUnionObj.lhs, opts); + let rhs = exprName(errUnionObj.rhs, opts); + return lhs + "!" + rhs; + + } case "struct": { const struct_name = zigAnalysis.decls[expr.struct[0].val.typeRef.refPath[0].declRef].name; let struct_body = ""; @@ -1084,7 +1091,6 @@ var zigAnalysis; return struct_body; } case "typeOf_peer": { - console.log(expr) let payloadHtml = "@TypeOf(" for (let i = 0; i < expr.typeOf_peer.length; i++) { let elem = zigAnalysis.exprs[expr.typeOf_peer[i]]; @@ -1094,7 +1100,6 @@ var zigAnalysis; } } payloadHtml += ")"; - console.log(payloadHtml) return payloadHtml; } @@ -1111,7 +1116,7 @@ var zigAnalysis; for (let i = 0; i < expr.array.length; i++) { if (i != 0) payloadHtml += ", "; let elem = zigAnalysis.exprs[expr.array[i]]; - payloadHtml += exprName(elem); + payloadHtml += exprName(elem, opts); } return payloadHtml + "}"; } @@ -1127,7 +1132,7 @@ var zigAnalysis; default: throw "TODO"; case "declRef": case "refPath": { - payloadHtml += exprName(call.func); + payloadHtml += exprName(call.func, opts); break; } } @@ -1135,7 +1140,7 @@ var zigAnalysis; for (let i = 0; i < call.args.length; i++) { if (i != 0) payloadHtml += ", "; - payloadHtml += exprName(call.args[i]); + payloadHtml += exprName(call.args[i], opts); } payloadHtml += ")"; @@ -1173,7 +1178,6 @@ var zigAnalysis; let typeObj = expr.type; if (typeof typeObj === 'number') typeObj = zigAnalysis.types[typeObj]; - switch (typeObj.kind) { default: throw "TODO"; case typeKinds.ComptimeExpr: @@ -1210,7 +1214,6 @@ var zigAnalysis; let sentinel = ptrObj.sentinel ? ":"+exprName(ptrObj.sentinel, opts) : ""; let is_mutable = !ptrObj.is_mutable ? "const " : ""; let name = ""; - console.log(ptrObj); switch (ptrObj.size) { default: console.log("TODO: implement unhandled pointer size case"); @@ -1352,40 +1355,29 @@ var zigAnalysis; { let errSetObj = /** @type {ErrSetType} */(typeObj); if (errSetObj.fields == null) { - if (wantHtml) { return 'anyerror'; - } else { - return "anyerror"; - } } else { - throw "TODO"; - // if (wantHtml) { - // return escapeHtml(typeObj.name); - // } else { - // return typeObj.name; - // } + // throw "TODO"; + let html = "error{" + errSetObj.fields[0].name + "}"; + return html; } } + case typeKinds.ErrorUnion: { - throw "TODO"; - // TODO: implement error union printing assuming that both - // payload and error union are walk results! - // let errUnionObj = /** @type {ErrUnionType} */(typeObj); - // let errSetTypeObj = /** @type {ErrSetType} */ (zigAnalysis.types[errUnionObj.err]); - // let payloadHtml = typeValueName(errUnionObj.payload, wantHtml, wantSubLink, null); - // if (fnDecl != null && errSetTypeObj.fn === fnDecl.value.type) { - // // function index parameter supplied and this is the inferred error set of it - // return "!" + payloadHtml; - // } else { - // return typeValueName(errUnionObj.err, wantHtml, wantSubLink, null) + "!" + payloadHtml; - // } + let errUnionObj = /** @type {ErrUnionType} */(typeObj); + let lhs = exprName(errUnionObj.lhs, opts); + let rhs = exprName(errUnionObj.rhs, opts); + return lhs + "!" + rhs; } case typeKinds.Fn: { let fnObj = /** @type {Fn} */(typeObj); let payloadHtml = ""; if (opts.wantHtml) { + if (fnObj.is_extern) { + payloadHtml += "pub \"extern\" "; + } payloadHtml += 'fn'; if (opts.fnDecl) { payloadHtml += ' '; @@ -1533,6 +1525,14 @@ var zigAnalysis; } payloadHtml += ') '; + if (fnObj.has_cc) { + let cc = zigAnalysis.types[fnObj.cc] + payloadHtml += "callconv(." + cc.name + ") "; + } + + if (fnObj.is_inferred_error) { + payloadHtml += "!"; + } if (fnObj.ret != null) { payloadHtml += exprName(fnObj.ret, opts); } else if (opts.wantHtml) { diff --git a/src/Autodoc.zig b/src/Autodoc.zig index 2111147060..380aab41c9 100644 --- a/src/Autodoc.zig +++ b/src/Autodoc.zig @@ -153,6 +153,9 @@ pub fn generateZirData(self: *Autodoc) !void { .type_type => .{ .Type = .{ .name = tmpbuf.toOwnedSlice() }, }, + .anyerror_type => .{ + .ErrorSet = .{ .name = tmpbuf.toOwnedSlice() }, + }, }, ); } @@ -429,10 +432,11 @@ const DocData = struct { name: []const u8, child: Expr, }, - ErrorUnion: struct { name: []const u8 }, + ErrorUnion: struct { lhs: Expr, rhs: Expr }, + // ErrorUnion: struct { name: []const u8 }, ErrorSet: struct { name: []const u8, - fields: []const Field, + fields: ?[]const Field = null, // TODO: fn field for inferred error sets? }, Enum: struct { @@ -454,6 +458,14 @@ const DocData = struct { src: ?usize = null, // index into astNodes ret: Expr, params: ?[]Expr = null, // (use src->fields to find names) + is_var_args: bool = false, + is_inferred_error: bool = false, + has_lib_name: bool = false, + has_cc: bool = false, + cc: ?usize = null, + has_align: bool = false, + is_test: bool = false, + is_extern: bool = false, }, BoundFn: struct { name: []const u8 }, Opaque: struct { name: []const u8 }, @@ -492,6 +504,7 @@ const DocData = struct { .Fn => |v| try printTypeBody(v, options, w), .Union => |v| try printTypeBody(v, options, w), .ErrorSet => |v| try printTypeBody(v, options, w), + .ErrorUnion => |v| try printTypeBody(v, options, w), .Enum => |v| try printTypeBody(v, options, w), .Int => |v| try printTypeBody(v, options, w), .Float => |v| try printTypeBody(v, options, w), @@ -588,6 +601,7 @@ const DocData = struct { enumLiteral: []const u8, // direct value typeOf: usize, // index in `exprs` typeOf_peer: []usize, + errorUnion: usize, // index in `exprs` as: As, sizeOf: usize, // index in `exprs` compileError: []const u8, @@ -617,7 +631,7 @@ const DocData = struct { \\{{ "{s}":{{}} }} , .{@tagName(self)}); }, - .type, .comptimeExpr, .call, .this, .declRef, .typeOf => |v| { + .type, .comptimeExpr, .call, .this, .declRef, .typeOf, .errorUnion => |v| { try w.print( \\{{ "{s}":{} }} , .{ @tagName(self), v }); @@ -853,7 +867,7 @@ fn walkInstruction( const literal = file.zir.nullTerminatedString(str_tok.start); const type_index = self.types.items.len; try self.types.append(self.arena, .{ - .EnumLiteral = .{ .name = "todo enum literal" }, + .EnumLiteral = .{ .name = literal }, }); return DocData.WalkResult{ @@ -872,8 +886,29 @@ fn walkInstruction( const pl_node = data[inst_index].pl_node; const extra = file.zir.extraData(Zir.Inst.Bin, pl_node.payload_index); - // TODO: return the actual error union instread of cheating - return self.walkRef(file, parent_scope, extra.data.rhs, need_type); + var lhs: DocData.WalkResult = try self.walkRef( + file, + parent_scope, + extra.data.lhs, + false, + ); + var rhs: DocData.WalkResult = try self.walkRef( + file, + parent_scope, + extra.data.rhs, + false, + ); + + const type_slot_index = self.types.items.len; + try self.types.append(self.arena, .{ .ErrorUnion = .{ + .lhs = lhs.expr, + .rhs = rhs.expr, + } }); + + return DocData.WalkResult{ + .typeRef = .{ .type = @enumToInt(Ref.type_type) }, + .expr = .{ .errorUnion = type_slot_index }, + }; }, .elem_type => { const un_node = data[inst_index].un_node; @@ -2744,14 +2779,43 @@ fn analyzeFunction( }; self.ast_nodes.items[self_ast_node_index].fields = param_ast_indexes.items; - self.types.items[type_slot_index] = .{ - .Fn = .{ - .name = "todo_name func", - .src = self_ast_node_index, - .params = param_type_refs.items, - .ret = ret_type_ref.expr, + self.types.items[type_slot_index] = switch (tags[inst_index]) { + .func, .func_inferred => blk: { + break :blk .{ + .Fn = .{ + .name = "todo_name func", + .src = self_ast_node_index, + .params = param_type_refs.items, + .ret = ret_type_ref.expr, + }, + }; }, + .func_extended => blk: { + const inst_data = data[inst_index].pl_node; + const extra = file.zir.extraData(Zir.Inst.ExtendedFunc, inst_data.payload_index); + + var cc_index: ?usize = null; + if (extra.data.bits.has_cc) { + const cc_ref = @intToEnum(Zir.Inst.Ref, file.zir.extra[extra.end]); + _ = try self.walkRef(file, scope, cc_ref, false); + cc_index = self.types.items.len - 1; + } + break :blk .{ + .Fn = .{ + .name = "todo_name func", + .src = self_ast_node_index, + .params = param_type_refs.items, + .ret = ret_type_ref.expr, + .is_extern = extra.data.bits.is_extern, + .has_cc = extra.data.bits.has_cc, + .is_inferred_error = extra.data.bits.is_inferred_error, + .cc = cc_index, + }, + }; + }, + else => unreachable, }; + return DocData.WalkResult{ .typeRef = .{ .type = @enumToInt(Ref.type_type) }, .expr = .{ .type = type_slot_index },