Commit 5a4005323f

Vallahor <vallahor91@gmail.com>
2022-05-23 02:41:18
add: sentiel
1 parent aa545db
Changed files (1)
src/Autodoc.zig
@@ -383,10 +383,12 @@ const DocData = struct {
         Pointer: struct {
             size: std.builtin.TypeInfo.Pointer.Size,
             child: Expr,
+            sentinel: ?usize = null,
         },
         Array: struct {
             len: Expr,
             child: Expr,
+            sentinel: ?usize = null,
         },
         Struct: struct {
             name: []const u8,
@@ -478,6 +480,11 @@ const DocData = struct {
                         \\
                     , .{@enumToInt(v.size)});
                     if (options.whitespace) |ws| try ws.outputIndent(w);
+                    try w.print(
+                        \\"sentinel": {},
+                        \\
+                    , .{v.sentinel});
+                    if (options.whitespace) |ws| try ws.outputIndent(w);
                     try w.print(
                         \\"child":
                     , .{});
@@ -754,11 +761,13 @@ fn walkInstruction(
                         .child = .{ .type = @enumToInt(Ref.u8_type) },
                     },
                 });
+                // const sentinel: ?usize = if (ptr.flags.has_sentinel) 0 else null;
                 const ptrTypeId = self.types.items.len;
                 try self.types.append(self.arena, .{
                     .Pointer = .{
                         .size = .One,
                         .child = .{ .type = arrTypeId },
+                        .sentinel = 0,
                         // TODO: add sentinel!
                     },
                 });
@@ -806,6 +815,24 @@ fn walkInstruction(
             // TODO: return the actual error union instread of cheating
             return self.walkRef(file, parent_scope, extra.data.rhs, need_type);
         },
+        .elem_type => {
+            const un_node = data[inst_index].un_node;
+            std.debug.print("un_node: {}\n", .{un_node});
+
+            var operand: DocData.WalkResult = try self.walkRef(
+                file,
+                parent_scope,
+                un_node.operand,
+                false,
+            );
+
+            std.debug.print("operand: {}\n", .{operand});
+
+            return DocData.WalkResult{
+                .typeRef = .{ .type = operand.typeRef.?.type },
+                .expr = .{ .type = operand.expr.type },
+            };
+        },
         .ptr_type_simple => {
             const ptr = data[inst_index].ptr_type_simple;
             const type_slot_index = self.types.items.len;
@@ -826,6 +853,14 @@ fn walkInstruction(
             const ptr = data[inst_index].ptr_type;
             const extra = file.zir.extraData(Zir.Inst.PtrType, ptr.payload_index);
 
+            std.debug.print("ptr = {}\n", .{ptr});
+            std.debug.print("extra = {any}\n", .{extra});
+
+            const sentinel: ?usize = if (ptr.flags.has_sentinel) 0 else null;
+
+            std.debug.print("sentinel = {} {d}\n", .{ ptr.flags.has_sentinel, sentinel });
+            std.debug.print("type = {d}\n", .{@enumToInt(Ref.type_type)});
+
             const type_slot_index = self.types.items.len;
             const elem_type_ref = try self.walkRef(
                 file,
@@ -837,9 +872,12 @@ fn walkInstruction(
                 .Pointer = .{
                     .size = ptr.size,
                     .child = elem_type_ref.expr,
+                    .sentinel = sentinel,
                 },
             });
+            std.debug.print("type = {d}\n", .{type_slot_index});
             return DocData.WalkResult{
+                // .typeRef = .{ .type = type_slot_index },
                 .typeRef = .{ .type = @enumToInt(Ref.type_type) },
                 .expr = .{ .type = type_slot_index },
             };
@@ -849,6 +887,11 @@ fn walkInstruction(
             const len = try self.walkRef(file, parent_scope, bin.lhs, false);
             const child = try self.walkRef(file, parent_scope, bin.rhs, false);
 
+            std.debug.print("AEHO\n", .{});
+            // std.debug.print("bin = {}\n", .{bin});
+            // std.debug.print("len = {}\n", .{len});
+            // std.debug.print("child = {}\n", .{child});
+
             const type_slot_index = self.types.items.len;
             try self.types.append(self.arena, .{
                 .Array = .{
@@ -861,6 +904,26 @@ fn walkInstruction(
                 .expr = .{ .type = type_slot_index },
             };
         },
+        .array_type_sentinel => {
+            const pl_node = data[inst_index].pl_node;
+            const extra = file.zir.extraData(Zir.Inst.ArrayTypeSentinel, pl_node.payload_index);
+            const len = try self.walkRef(file, parent_scope, extra.data.len, false);
+            const sentinel = try self.walkRef(file, parent_scope, extra.data.sentinel, false);
+            const elem_type = try self.walkRef(file, parent_scope, extra.data.elem_type, false);
+
+            const type_slot_index = self.types.items.len;
+            try self.types.append(self.arena, .{
+                .Array = .{
+                    .len = len.expr,
+                    .child = elem_type.expr,
+                    .sentinel = sentinel.expr.int.value,
+                },
+            });
+            return DocData.WalkResult{
+                .typeRef = .{ .type = @enumToInt(Ref.type_type) },
+                .expr = .{ .type = type_slot_index },
+            };
+        },
         .array_init => {
             const pl_node = data[inst_index].pl_node;
             const extra = file.zir.extraData(Zir.Inst.MultiOp, pl_node.payload_index);
@@ -875,6 +938,7 @@ fn walkInstruction(
                 // we only ask to figure out type info for the first element
                 // as it will be used later on to find out the array type!
                 const wr = try self.walkRef(file, parent_scope, op, idx == 0);
+                std.debug.print("wr: {any}\n", .{wr});
 
                 if (idx == 0) {
                     array_type = wr.typeRef;
@@ -886,6 +950,102 @@ fn walkInstruction(
                 array_data[idx] = wr.expr.as.exprArg;
             }
 
+            const type_slot_index = self.types.items.len;
+            try self.types.append(self.arena, .{
+                .Array = .{ .len = .{
+                    .int = .{
+                        .value = operands.len,
+                        .negated = false,
+                    },
+                }, .child = array_type.? },
+            });
+
+            return DocData.WalkResult{
+                .typeRef = .{ .type = type_slot_index },
+                .expr = .{ .array = array_data },
+            };
+        },
+        .array_init_sent => {
+            const pl_node = data[inst_index].pl_node;
+            const extra = file.zir.extraData(Zir.Inst.MultiOp, pl_node.payload_index);
+            const operands = file.zir.refSlice(extra.end, extra.data.operands_len - 1);
+            const array_data = try self.arena.alloc(usize, operands.len);
+
+            // TODO: make sure that you want the array to be fully normalized for real
+            // then update this code to conform to your choice.
+
+            var array_type: ?DocData.Expr = null;
+            for (operands) |op, idx| {
+                // we only ask to figure out type info for the first element
+                // as it will be used later on to find out the array type!
+                const wr = try self.walkRef(file, parent_scope, op, idx == 0);
+                std.debug.print("wr: {any}\n", .{wr});
+                if (idx == 0) {
+                    array_type = wr.typeRef;
+                }
+
+                // We know that Zir wraps every operand in an @as expression
+                // so we want to peel it away and only save the target type
+                // once, since we need it later to define the array type.
+                array_data[idx] = wr.expr.as.exprArg;
+            }
+
+            // std.debug.print("array: {any}\n", .{array_data});
+
+            const type_slot_index = self.types.items.len;
+            try self.types.append(self.arena, .{
+                .Array = .{ .len = .{
+                    .int = .{
+                        .value = operands.len,
+                        .negated = false,
+                    },
+                }, .child = array_type.?, .sentinel = 0 },
+            });
+
+            return DocData.WalkResult{
+                .typeRef = .{ .type = type_slot_index },
+                .expr = .{ .array = array_data },
+            };
+        },
+        .array_init_anon => {
+            const pl_node = data[inst_index].pl_node;
+            const extra = file.zir.extraData(Zir.Inst.MultiOp, pl_node.payload_index);
+            const operands = file.zir.refSlice(extra.end, extra.data.operands_len);
+            const array_data = try self.arena.alloc(usize, operands.len);
+
+            // TODO: make sure that you want the array to be fully normalized for real
+            // then update this code to conform to your choice.
+
+            // std.debug.print("extra: {}\n", .{extra});
+            // std.debug.print("operands: {any}\n", .{operands});
+
+            var array_type: ?DocData.Expr = null;
+            for (operands) |op, idx| {
+                // we only ask to figure out type info for the first element
+                // as it will be used later on to find out the array type!
+                const wr = try self.walkRef(file, parent_scope, op, idx == 0);
+                // std.debug.print("wr: {any}\n", .{wr});
+
+                if (idx == 0) {
+                    array_type = wr.typeRef;
+                }
+                // std.debug.print("type: {}\n", .{@intToEnum(Ref, wr.typeRef.?.type)});
+
+                // create an untion to hold more than one type
+                switch (@intToEnum(Ref, wr.typeRef.?.type)) {
+                    .comptime_int_type => {
+                        array_data[idx] = wr.expr.int.value;
+                    },
+                    .comptime_float_type => {
+                        unreachable;
+                        // array_data[idx] = wr.expr.float;
+                    },
+                    else => continue,
+                }
+            }
+
+            // std.debug.print("array: {any}\n", .{array_data});
+
             const type_slot_index = self.types.items.len;
             try self.types.append(self.arena, .{
                 .Array = .{
@@ -904,6 +1064,20 @@ fn walkInstruction(
                 .expr = .{ .array = array_data },
             };
         },
+        // .validate_array_init_ty => {
+        //     const un_node = data[inst_index].un_node;
+        //     var operand: DocData.WalkResult = try self.walkRef(
+        //         file,
+        //         parent_scope,
+        //         un_node.operand,
+        //         need_type,
+        //     );
+        //
+        //     std.debug.print("validate _ array => {}\n", .{un_node});
+        //     std.debug.print("operand = {}\n", .{operand});
+        //
+        //     return operand;
+        // },
         .float => {
             const float = data[inst_index].float;
             return DocData.WalkResult{