diff --git a/lib/docs/main.js b/lib/docs/main.js index ee2d8ac4b4e891f85dab20fdaf01a1faf1c1680d..2de584a66685fb5a7332df24fdf29611203776c9 100644 --- a/lib/docs/main.js +++ b/lib/docs/main.js @@ -1062,6 +1062,97 @@ var zigAnalysis; function exprName(expr, opts) { switch (Object.keys(expr)[0]) { default: throw "oh no"; + case "sizeOf" : { + const sizeOf = zigAnalysis.exprs[expr.sizeOf]; + return "sizeOf(" + exprName(sizeOf, opts) + ")"; + } + case "binOpIndex" : { + const binOpIndex = zigAnalysis.exprs[expr.binOpIndex]; + return exprName(binOpIndex, opts); + } + case "binOp": { + const lhsOp = zigAnalysis.exprs[expr.binOp.lhs]; + const rhsOp = zigAnalysis.exprs[expr.binOp.rhs]; + let lhs = exprName(lhsOp, opts); + let rhs = exprName(rhsOp, opts); + + let print_lhs = ""; + let print_rhs = ""; + if (lhsOp['binOpIndex']) { + print_lhs = "(" + lhs + ")"; + } else { + print_lhs = lhs; + } + if (rhsOp['binOpIndex']) { + print_rhs = "(" + rhs + ")"; + } else { + print_rhs = rhs; + } + + let operator = ""; + // binOp.kind is described at Autodoc.zig + // Expr section in BinOp struct + switch (expr.binOp.opKind) { + case 0: { + operator += "+"; + break; + } + case 1: { + operator += "-"; + break; + } + case 2: { + operator += "*"; + break; + } + case 3: { + let print_div = ""; + if (expr.binOp.exact) { + print_div = "@divExact("; + } + if (expr.binOp.floor) { + print_div = "@divFloor("; + } + if (expr.binOp.trunc) { + print_div = "@divTrunc("; + } + return print_div + print_lhs + ", " + print_rhs + ")"; + } + case 4: { + operator += "mod" + break; + } + case 5: { + operator += "rem" + break; + } + case 6: { + operator += "<<"; + break; + } + case 7: { + operator += ">>"; + break; + } + case 8: { + operator += "&"; + break; + } + case 7: { + operator += "|"; + break; + } + default: console.log("operator not handled yet or doesn't exist!"); + }; + if (expr.binOp.wrap) { + operator += "%"; + } + if (expr.binOp.sat) { + operator += "|"; + } + return print_lhs + " " + operator + " " + print_rhs; + + } case "errorUnion": { const errUnionObj = zigAnalysis.types[expr.errorUnion]; let lhs = exprName(errUnionObj.lhs, opts); diff --git a/src/Autodoc.zig b/src/Autodoc.zig index e99fe500f833199a9c71802a0727107e84ca4276..ea65078f59c1be97446012c3d6d7b7d2f37628b8 100644 --- a/src/Autodoc.zig +++ b/src/Autodoc.zig @@ -655,6 +655,28 @@ const DocData = struct { sizeOf: usize, // index in `exprs` compileError: []const u8, string: []const u8, // direct value + // Index a `type` like struct with expressions + // it's necessary because when a caller ask by a binOp maybe there are + // more binary op inside them, so the caller get's the current `exprs` index + // and the binOp can walk the tree preserving the first index of the tree + // for examples see `.mul` and `analyzeFunctionExtended` in `has_align` section + binOp: BinOp, + binOpIndex: usize, + const BinOp = struct { + lhs: usize, // index in `exprs` + rhs: usize, // index in `exprs` + // opKind + // Identify the operator in js + // 0: add, 1: sub, 2: mul, 3: div, 4: mod, 5: rem, 6: shl, 7: shr, 8: bitwise_and, 9: bitwise_or + // Others binOp are not handled yet + opKind: usize = 0, + // flags to operations + wrap: bool = false, + sat: bool = false, + exact: bool = false, + floor: bool = false, + trunc: bool = false, + }; const As = struct { typeRefArg: ?usize, // index in `exprs` exprArg: usize, // index in `exprs` @@ -701,7 +723,11 @@ const DocData = struct { \\{{ "bool":{} }} , .{v}); }, - .sizeOf => |v| try std.json.stringify(v, options, w), + .sizeOf => |v| { + try w.print( + \\{{ "sizeOf":{} }} + , .{v}); + }, .fieldRef => |v| try std.json.stringify( struct { fieldRef: FieldRef }{ .fieldRef = v }, options, @@ -725,6 +751,16 @@ const DocData = struct { try w.print("{s}", .{comma}); } }, + .binOp => |v| try std.json.stringify( + struct { binOp: BinOp }{ .binOp = v }, + options, + w, + ), + .binOpIndex => |v| try std.json.stringify( + struct { binOpIndex: usize }{ .binOpIndex = v }, + options, + w, + ), .typeOf_peer => |v| try std.json.stringify( struct { typeOf_peer: []usize }{ .typeOf_peer = v }, options, @@ -931,6 +967,381 @@ fn walkInstruction( .expr = .{ .int = .{ .value = int } }, }; }, + .add => { + const pl_node = data[inst_index].pl_node; + const extra = file.zir.extraData(Zir.Inst.Bin, pl_node.payload_index); + + const binop_index = self.exprs.items.len; + try self.exprs.append(self.arena, .{ .binOp = .{ .lhs = 0, .rhs = 0 } }); + + 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 lhs_index = self.exprs.items.len; + try self.exprs.append(self.arena, lhs.expr); + const rhs_index = self.exprs.items.len; + try self.exprs.append(self.arena, rhs.expr); + self.exprs.items[binop_index] = .{ .binOp = .{ .lhs = lhs_index, .rhs = rhs_index, .opKind = 0 } }; + + return DocData.WalkResult{ + .typeRef = .{ .type = @enumToInt(Ref.type_type) }, + .expr = .{ .binOpIndex = binop_index }, + }; + }, + .addwrap => { + const pl_node = data[inst_index].pl_node; + const extra = file.zir.extraData(Zir.Inst.Bin, pl_node.payload_index); + + const binop_index = self.exprs.items.len; + try self.exprs.append(self.arena, .{ .binOp = .{ .lhs = 0, .rhs = 0 } }); + + 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 lhs_index = self.exprs.items.len; + try self.exprs.append(self.arena, lhs.expr); + const rhs_index = self.exprs.items.len; + try self.exprs.append(self.arena, rhs.expr); + self.exprs.items[binop_index] = .{ .binOp = .{ .lhs = lhs_index, .rhs = rhs_index, .wrap = true, .opKind = 0 } }; + + return DocData.WalkResult{ + .typeRef = .{ .type = @enumToInt(Ref.type_type) }, + .expr = .{ .binOpIndex = binop_index }, + }; + }, + .add_sat => { + const pl_node = data[inst_index].pl_node; + const extra = file.zir.extraData(Zir.Inst.Bin, pl_node.payload_index); + + const binop_index = self.exprs.items.len; + try self.exprs.append(self.arena, .{ .binOp = .{ .lhs = 0, .rhs = 0 } }); + + 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 lhs_index = self.exprs.items.len; + try self.exprs.append(self.arena, lhs.expr); + const rhs_index = self.exprs.items.len; + try self.exprs.append(self.arena, rhs.expr); + self.exprs.items[binop_index] = .{ .binOp = .{ .lhs = lhs_index, .rhs = rhs_index, .sat = true, .opKind = 0 } }; + + return DocData.WalkResult{ + .typeRef = .{ .type = @enumToInt(Ref.type_type) }, + .expr = .{ .binOpIndex = binop_index }, + }; + }, + + .sub => { + const pl_node = data[inst_index].pl_node; + const extra = file.zir.extraData(Zir.Inst.Bin, pl_node.payload_index); + + const binop_index = self.exprs.items.len; + try self.exprs.append(self.arena, .{ .binOp = .{ .lhs = 0, .rhs = 0 } }); + + 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 lhs_index = self.exprs.items.len; + try self.exprs.append(self.arena, lhs.expr); + const rhs_index = self.exprs.items.len; + try self.exprs.append(self.arena, rhs.expr); + self.exprs.items[binop_index] = .{ .binOp = .{ .lhs = lhs_index, .rhs = rhs_index, .opKind = 1 } }; + + return DocData.WalkResult{ + .typeRef = .{ .type = @enumToInt(Ref.type_type) }, + .expr = .{ .binOpIndex = binop_index }, + }; + }, + .subwrap => { + const pl_node = data[inst_index].pl_node; + const extra = file.zir.extraData(Zir.Inst.Bin, pl_node.payload_index); + + const binop_index = self.exprs.items.len; + try self.exprs.append(self.arena, .{ .binOp = .{ .lhs = 0, .rhs = 0 } }); + + 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 lhs_index = self.exprs.items.len; + try self.exprs.append(self.arena, lhs.expr); + const rhs_index = self.exprs.items.len; + try self.exprs.append(self.arena, rhs.expr); + self.exprs.items[binop_index] = .{ .binOp = .{ .lhs = lhs_index, .rhs = rhs_index, .wrap = true, .opKind = 1 } }; + + return DocData.WalkResult{ + .typeRef = .{ .type = @enumToInt(Ref.type_type) }, + .expr = .{ .binOpIndex = binop_index }, + }; + }, + .sub_sat => { + const pl_node = data[inst_index].pl_node; + const extra = file.zir.extraData(Zir.Inst.Bin, pl_node.payload_index); + + const binop_index = self.exprs.items.len; + try self.exprs.append(self.arena, .{ .binOp = .{ .lhs = 0, .rhs = 0 } }); + + 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 lhs_index = self.exprs.items.len; + try self.exprs.append(self.arena, lhs.expr); + const rhs_index = self.exprs.items.len; + try self.exprs.append(self.arena, rhs.expr); + self.exprs.items[binop_index] = .{ .binOp = .{ .lhs = lhs_index, .rhs = rhs_index, .sat = true, .opKind = 1 } }; + + return DocData.WalkResult{ + .typeRef = .{ .type = @enumToInt(Ref.type_type) }, + .expr = .{ .binOpIndex = binop_index }, + }; + }, + + .mul => { + const pl_node = data[inst_index].pl_node; + const extra = file.zir.extraData(Zir.Inst.Bin, pl_node.payload_index); + + const binop_index = self.exprs.items.len; + try self.exprs.append(self.arena, .{ .binOp = .{ .lhs = 0, .rhs = 0 } }); + + 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 lhs_index = self.exprs.items.len; + try self.exprs.append(self.arena, lhs.expr); + const rhs_index = self.exprs.items.len; + try self.exprs.append(self.arena, rhs.expr); + self.exprs.items[binop_index] = .{ .binOp = .{ .lhs = lhs_index, .rhs = rhs_index, .opKind = 2 } }; + + return DocData.WalkResult{ + .typeRef = .{ .type = @enumToInt(Ref.type_type) }, + .expr = .{ .binOpIndex = binop_index }, + }; + }, + .mulwrap => { + const pl_node = data[inst_index].pl_node; + const extra = file.zir.extraData(Zir.Inst.Bin, pl_node.payload_index); + + const binop_index = self.exprs.items.len; + try self.exprs.append(self.arena, .{ .binOp = .{ .lhs = 0, .rhs = 0 } }); + + 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 lhs_index = self.exprs.items.len; + try self.exprs.append(self.arena, lhs.expr); + const rhs_index = self.exprs.items.len; + try self.exprs.append(self.arena, rhs.expr); + self.exprs.items[binop_index] = .{ .binOp = .{ .lhs = lhs_index, .rhs = rhs_index, .wrap = true, .opKind = 2 } }; + + return DocData.WalkResult{ + .typeRef = .{ .type = @enumToInt(Ref.type_type) }, + .expr = .{ .binOpIndex = binop_index }, + }; + }, + .mul_sat => { + const pl_node = data[inst_index].pl_node; + const extra = file.zir.extraData(Zir.Inst.Bin, pl_node.payload_index); + + const binop_index = self.exprs.items.len; + try self.exprs.append(self.arena, .{ .binOp = .{ .lhs = 0, .rhs = 0 } }); + + 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 lhs_index = self.exprs.items.len; + try self.exprs.append(self.arena, lhs.expr); + const rhs_index = self.exprs.items.len; + try self.exprs.append(self.arena, rhs.expr); + self.exprs.items[binop_index] = .{ .binOp = .{ .lhs = lhs_index, .rhs = rhs_index, .sat = true, .opKind = 2 } }; + + return DocData.WalkResult{ + .typeRef = .{ .type = @enumToInt(Ref.type_type) }, + .expr = .{ .binOpIndex = binop_index }, + }; + }, + + .div_exact => { + const pl_node = data[inst_index].pl_node; + const extra = file.zir.extraData(Zir.Inst.Bin, pl_node.payload_index); + + const binop_index = self.exprs.items.len; + try self.exprs.append(self.arena, .{ .binOp = .{ .lhs = 0, .rhs = 0 } }); + + 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 lhs_index = self.exprs.items.len; + try self.exprs.append(self.arena, lhs.expr); + const rhs_index = self.exprs.items.len; + try self.exprs.append(self.arena, rhs.expr); + self.exprs.items[binop_index] = .{ .binOp = .{ .lhs = lhs_index, .rhs = rhs_index, .exact = true, .opKind = 3 } }; + + return DocData.WalkResult{ + .typeRef = .{ .type = @enumToInt(Ref.type_type) }, + .expr = .{ .binOpIndex = binop_index }, + }; + }, + .div_floor => { + const pl_node = data[inst_index].pl_node; + const extra = file.zir.extraData(Zir.Inst.Bin, pl_node.payload_index); + + const binop_index = self.exprs.items.len; + try self.exprs.append(self.arena, .{ .binOp = .{ .lhs = 0, .rhs = 0 } }); + + 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 lhs_index = self.exprs.items.len; + try self.exprs.append(self.arena, lhs.expr); + const rhs_index = self.exprs.items.len; + try self.exprs.append(self.arena, rhs.expr); + self.exprs.items[binop_index] = .{ .binOp = .{ .lhs = lhs_index, .rhs = rhs_index, .floor = true, .opKind = 3 } }; + + return DocData.WalkResult{ + .typeRef = .{ .type = @enumToInt(Ref.type_type) }, + .expr = .{ .binOpIndex = binop_index }, + }; + }, + .div_trunc => { + const pl_node = data[inst_index].pl_node; + const extra = file.zir.extraData(Zir.Inst.Bin, pl_node.payload_index); + + const binop_index = self.exprs.items.len; + try self.exprs.append(self.arena, .{ .binOp = .{ .lhs = 0, .rhs = 0 } }); + + 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 lhs_index = self.exprs.items.len; + try self.exprs.append(self.arena, lhs.expr); + const rhs_index = self.exprs.items.len; + try self.exprs.append(self.arena, rhs.expr); + self.exprs.items[binop_index] = .{ .binOp = .{ .lhs = lhs_index, .rhs = rhs_index, .trunc = true, .opKind = 3 } }; + + return DocData.WalkResult{ + .typeRef = .{ .type = @enumToInt(Ref.type_type) }, + .expr = .{ .binOpIndex = binop_index }, + }; + }, .error_union_type => { const pl_node = data[inst_index].pl_node; const extra = file.zir.extraData(Zir.Inst.Bin, pl_node.payload_index); @@ -1435,6 +1846,14 @@ fn walkInstruction( const dest_type_idx = self.exprs.items.len; try self.exprs.append(self.arena, dest_type_walk.expr); + const sep = "=" ** 200; + std.debug.print("{s}\n", .{sep}); + std.debug.print("AS NODE\n", .{}); + std.debug.print("extra = {any}\n", .{extra}); + std.debug.print("desty_type_walk = {any}\n", .{dest_type_walk}); + std.debug.print("operand = {any}\n", .{operand}); + std.debug.print("{s}\n", .{sep}); + // TODO: there's something wrong with how both `as` and `WalkrResult` // try to store type information. return DocData.WalkResult{ @@ -2886,7 +3305,14 @@ fn analyzeFunctionExtended( if (extra.data.bits.has_align) { const align_ref = @intToEnum(Zir.Inst.Ref, file.zir.extra[extra_index]); align_index = self.exprs.items.len; - _ = try self.walkRef(file, scope, align_ref, false); + const result = try self.walkRef(file, scope, align_ref, false); + + const sep = "=" ** 200; + std.debug.print("{s}\n", .{sep}); + std.debug.print("ALIGN\n", .{}); + std.debug.print("align_ref = {any}\n", .{align_ref}); + std.debug.print("result = {any}\n", .{result}); + std.debug.print("{s}\n", .{sep}); } self.types.items[type_slot_index] = .{