Commit 9f6bdc4bbe

Vallahor <vallahor91@gmail.com>
2022-05-29 08:36:02
add: binOp WIP
1 parent c0c9925
Changed files (2)
lib
docs
src
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);
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] = .{