mirror of
https://github.com/ziglang/zig.git
synced 2024-11-15 16:45:27 +00:00
stage2: array types
This commit is contained in:
parent
3eb8f7be10
commit
7c15c9428e
@ -2902,7 +2902,7 @@ pub fn floatSub(self: *Module, scope: *Scope, float_type: Type, src: usize, lhs:
|
||||
return Value.initPayload(val_payload);
|
||||
}
|
||||
|
||||
pub fn singlePtrType(self: *Module, scope: *Scope, src: usize, mutable: bool, elem_ty: Type) error{OutOfMemory}!Type {
|
||||
pub fn singlePtrType(self: *Module, scope: *Scope, src: usize, mutable: bool, elem_ty: Type) Allocator.Error!Type {
|
||||
const type_payload = try scope.arena().create(Type.Payload.Pointer);
|
||||
type_payload.* = .{
|
||||
.base = .{ .tag = if (mutable) .single_mut_pointer else .single_const_pointer },
|
||||
@ -2911,6 +2911,71 @@ pub fn singlePtrType(self: *Module, scope: *Scope, src: usize, mutable: bool, el
|
||||
return Type.initPayload(&type_payload.base);
|
||||
}
|
||||
|
||||
pub fn optionalType(self: *Module, scope: *Scope, child_type: Type) Allocator.Error!Type {
|
||||
return Type.initPayload(switch (child_type.tag()) {
|
||||
.single_const_pointer => blk: {
|
||||
const payload = try scope.arena().create(Type.Payload.Pointer);
|
||||
payload.* = .{
|
||||
.base = .{ .tag = .optional_single_const_pointer },
|
||||
.pointee_type = child_type.elemType(),
|
||||
};
|
||||
break :blk &payload.base;
|
||||
},
|
||||
.single_mut_pointer => blk: {
|
||||
const payload = try scope.arena().create(Type.Payload.Pointer);
|
||||
payload.* = .{
|
||||
.base = .{ .tag = .optional_single_mut_pointer },
|
||||
.pointee_type = child_type.elemType(),
|
||||
};
|
||||
break :blk &payload.base;
|
||||
},
|
||||
else => blk: {
|
||||
const payload = try scope.arena().create(Type.Payload.Optional);
|
||||
payload.* = .{
|
||||
.child_type = child_type,
|
||||
};
|
||||
break :blk &payload.base;
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
pub fn arrayType(self: *Module, scope: *Scope, len: u64, sentinel: ?Value, elem_type: Type) Allocator.Error!Type {
|
||||
if (elem_type.eql(Type.initTag(.u8))) {
|
||||
if (sentinel) |some| {
|
||||
if (some.eql(Value.initTag(.zero))) {
|
||||
const payload = try scope.arena().create(Type.Payload.Array_u8_Sentinel0);
|
||||
payload.* = .{
|
||||
.len = len,
|
||||
};
|
||||
return Type.initPayload(&payload.base);
|
||||
}
|
||||
} else {
|
||||
const payload = try scope.arena().create(Type.Payload.Array_u8);
|
||||
payload.* = .{
|
||||
.len = len,
|
||||
};
|
||||
return Type.initPayload(&payload.base);
|
||||
}
|
||||
}
|
||||
|
||||
if (sentinel) |some| {
|
||||
const payload = try scope.arena().create(Type.Payload.ArraySentinel);
|
||||
payload.* = .{
|
||||
.len = len,
|
||||
.sentinel = some,
|
||||
.elem_type = elem_type,
|
||||
};
|
||||
return Type.initPayload(&payload.base);
|
||||
}
|
||||
|
||||
const payload = try scope.arena().create(Type.Payload.Array);
|
||||
payload.* = .{
|
||||
.len = len,
|
||||
.elem_type = elem_type,
|
||||
};
|
||||
return Type.initPayload(&payload.base);
|
||||
}
|
||||
|
||||
pub fn dumpInst(self: *Module, scope: *Scope, inst: *Inst) void {
|
||||
const zir_module = scope.namespace();
|
||||
const source = zir_module.getSource(self) catch @panic("dumpInst failed to get source");
|
||||
|
@ -128,6 +128,8 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node) InnerEr
|
||||
.Break => return rlWrap(mod, scope, rl, try breakExpr(mod, scope, node.castTag(.Break).?)),
|
||||
.PtrType => return rlWrap(mod, scope, rl, try ptrType(mod, scope, node.castTag(.PtrType).?)),
|
||||
.GroupedExpression => return expr(mod, scope, rl, node.castTag(.GroupedExpression).?.expr),
|
||||
.ArrayType => return rlWrap(mod, scope, rl, try arrayType(mod, scope, node.castTag(.ArrayType).?)),
|
||||
.ArrayTypeSentinel => return rlWrap(mod, scope, rl, try arrayTypeSentinel(mod, scope, node.castTag(.ArrayTypeSentinel).?)),
|
||||
|
||||
.Defer => return mod.failNode(scope, node, "TODO implement astgen.expr for .Defer", .{}),
|
||||
.Catch => return mod.failNode(scope, node, "TODO implement astgen.expr for .Catch", .{}),
|
||||
@ -141,8 +143,6 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node) InnerEr
|
||||
.NegationWrap => return mod.failNode(scope, node, "TODO implement astgen.expr for .NegationWrap", .{}),
|
||||
.Resume => return mod.failNode(scope, node, "TODO implement astgen.expr for .Resume", .{}),
|
||||
.Try => return mod.failNode(scope, node, "TODO implement astgen.expr for .Try", .{}),
|
||||
.ArrayType => return mod.failNode(scope, node, "TODO implement astgen.expr for .ArrayType", .{}),
|
||||
.ArrayTypeSentinel => return mod.failNode(scope, node, "TODO implement astgen.expr for .ArrayTypeSentinel", .{}),
|
||||
.SliceType => return mod.failNode(scope, node, "TODO implement astgen.expr for .SliceType", .{}),
|
||||
.Slice => return mod.failNode(scope, node, "TODO implement astgen.expr for .Slice", .{}),
|
||||
.ArrayAccess => return mod.failNode(scope, node, "TODO implement astgen.expr for .ArrayAccess", .{}),
|
||||
@ -485,6 +485,48 @@ fn ptrType(mod: *Module, scope: *Scope, node: *ast.Node.PtrType) InnerError!*zir
|
||||
return addZIRInst(mod, scope, src, zir.Inst.PtrType, .{ .child_type = child_type }, kw_args);
|
||||
}
|
||||
|
||||
fn arrayType(mod: *Module, scope: *Scope, node: *ast.Node.ArrayType) !*zir.Inst {
|
||||
const tree = scope.tree();
|
||||
const src = tree.token_locs[node.op_token].start;
|
||||
const meta_type = try addZIRInstConst(mod, scope, src, .{
|
||||
.ty = Type.initTag(.type),
|
||||
.val = Value.initTag(.type_type),
|
||||
});
|
||||
const usize_type = try addZIRInstConst(mod, scope, src, .{
|
||||
.ty = Type.initTag(.type),
|
||||
.val = Value.initTag(.usize_type),
|
||||
});
|
||||
|
||||
const len = try expr(mod, scope, .{ .ty = usize_type }, node.len_expr);
|
||||
const child_type = try expr(mod, scope, .{ .ty = meta_type }, node.rhs);
|
||||
|
||||
return addZIRBinOp(mod, scope, src, .array_type, len, child_type);
|
||||
}
|
||||
|
||||
fn arrayTypeSentinel(mod: *Module, scope: *Scope, node: *ast.Node.ArrayTypeSentinel) !*zir.Inst {
|
||||
const tree = scope.tree();
|
||||
const src = tree.token_locs[node.op_token].start;
|
||||
const meta_type = try addZIRInstConst(mod, scope, src, .{
|
||||
.ty = Type.initTag(.type),
|
||||
.val = Value.initTag(.type_type),
|
||||
});
|
||||
const usize_type = try addZIRInstConst(mod, scope, src, .{
|
||||
.ty = Type.initTag(.type),
|
||||
.val = Value.initTag(.usize_type),
|
||||
});
|
||||
|
||||
const len = try expr(mod, scope, .{ .ty = usize_type }, node.len_expr);
|
||||
const sentinel_uncasted = try expr(mod, scope, .none, node.sentinel);
|
||||
const elem_type = try expr(mod, scope, .{ .ty = meta_type }, node.rhs);
|
||||
const sentinel = try addZIRBinOp(mod, scope, src, .as, elem_type, sentinel_uncasted);
|
||||
|
||||
return addZIRInst(mod, scope, src, zir.Inst.ArrayTypeSentinel, .{
|
||||
.len = len,
|
||||
.sentinel = sentinel,
|
||||
.elem_type = elem_type,
|
||||
}, .{});
|
||||
}
|
||||
|
||||
fn unwrapOptional(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.SimpleSuffixOp) InnerError!*zir.Inst {
|
||||
const tree = scope.tree();
|
||||
const src = tree.token_locs[node.rtoken].start;
|
||||
|
@ -65,7 +65,7 @@ pub const Type = extern union {
|
||||
.fn_ccc_void_no_args => return .Fn,
|
||||
.function => return .Fn,
|
||||
|
||||
.array, .array_u8_sentinel_0 => return .Array,
|
||||
.array, .array_u8_sentinel_0, .array_u8, .array_sentinel => return .Array,
|
||||
.single_const_pointer => return .Pointer,
|
||||
.single_mut_pointer => return .Pointer,
|
||||
.single_const_pointer_to_comptime_int => return .Pointer,
|
||||
@ -330,6 +330,7 @@ pub const Type = extern union {
|
||||
=> unreachable,
|
||||
|
||||
.array_u8_sentinel_0 => return self.copyPayloadShallow(allocator, Payload.Array_u8_Sentinel0),
|
||||
.array_u8 => return self.copyPayloadShallow(allocator, Payload.Array_u8),
|
||||
.array => {
|
||||
const payload = @fieldParentPtr(Payload.Array, "base", self.ptr_otherwise);
|
||||
const new_payload = try allocator.create(Payload.Array);
|
||||
@ -340,6 +341,17 @@ pub const Type = extern union {
|
||||
};
|
||||
return Type{ .ptr_otherwise = &new_payload.base };
|
||||
},
|
||||
.array_sentinel => {
|
||||
const payload = @fieldParentPtr(Payload.ArraySentinel, "base", self.ptr_otherwise);
|
||||
const new_payload = try allocator.create(Payload.ArraySentinel);
|
||||
new_payload.* = .{
|
||||
.base = payload.base,
|
||||
.len = payload.len,
|
||||
.sentinel = try payload.sentinel.copy(allocator),
|
||||
.elem_type = try payload.elem_type.copy(allocator),
|
||||
};
|
||||
return Type{ .ptr_otherwise = &new_payload.base };
|
||||
},
|
||||
.int_signed => return self.copyPayloadShallow(allocator, Payload.IntSigned),
|
||||
.int_unsigned => return self.copyPayloadShallow(allocator, Payload.IntUnsigned),
|
||||
.function => {
|
||||
@ -445,6 +457,10 @@ pub const Type = extern union {
|
||||
try payload.return_type.format("", .{}, out_stream);
|
||||
},
|
||||
|
||||
.array_u8 => {
|
||||
const payload = @fieldParentPtr(Payload.Array_u8, "base", ty.ptr_otherwise);
|
||||
return out_stream.print("[{}]u8", .{payload.len});
|
||||
},
|
||||
.array_u8_sentinel_0 => {
|
||||
const payload = @fieldParentPtr(Payload.Array_u8_Sentinel0, "base", ty.ptr_otherwise);
|
||||
return out_stream.print("[{}:0]u8", .{payload.len});
|
||||
@ -455,6 +471,12 @@ pub const Type = extern union {
|
||||
ty = payload.elem_type;
|
||||
continue;
|
||||
},
|
||||
.array_sentinel => {
|
||||
const payload = @fieldParentPtr(Payload.ArraySentinel, "base", ty.ptr_otherwise);
|
||||
try out_stream.print("[{}:{}]", .{ payload.len, payload.sentinel });
|
||||
ty = payload.elem_type;
|
||||
continue;
|
||||
},
|
||||
.single_const_pointer => {
|
||||
const payload = @fieldParentPtr(Payload.Pointer, "base", ty.ptr_otherwise);
|
||||
try out_stream.writeAll("*const ");
|
||||
@ -588,6 +610,8 @@ pub const Type = extern union {
|
||||
=> true,
|
||||
// TODO lazy types
|
||||
.array => self.elemType().hasCodeGenBits() and self.arrayLen() != 0,
|
||||
.array_u8 => self.arrayLen() != 0,
|
||||
.array_sentinel => self.elemType().hasCodeGenBits(),
|
||||
.single_const_pointer => self.elemType().hasCodeGenBits(),
|
||||
.single_mut_pointer => self.elemType().hasCodeGenBits(),
|
||||
.int_signed => self.cast(Payload.IntSigned).?.bits == 0,
|
||||
@ -616,6 +640,7 @@ pub const Type = extern union {
|
||||
.i8,
|
||||
.bool,
|
||||
.array_u8_sentinel_0,
|
||||
.array_u8,
|
||||
=> return 1,
|
||||
|
||||
.fn_noreturn_no_args, // represents machine code; not a pointer
|
||||
@ -659,7 +684,7 @@ pub const Type = extern union {
|
||||
|
||||
.anyerror => return 2, // TODO revisit this when we have the concept of the error tag type
|
||||
|
||||
.array => return self.cast(Payload.Array).?.elem_type.abiAlignment(target),
|
||||
.array, .array_sentinel => return self.elemType().abiAlignment(target),
|
||||
|
||||
.int_signed, .int_unsigned => {
|
||||
const bits: u16 = if (self.cast(Payload.IntSigned)) |pl|
|
||||
@ -717,12 +742,18 @@ pub const Type = extern union {
|
||||
.bool,
|
||||
=> return 1,
|
||||
|
||||
.array_u8_sentinel_0 => @fieldParentPtr(Payload.Array_u8_Sentinel0, "base", self.ptr_otherwise).len,
|
||||
.array_u8 => @fieldParentPtr(Payload.Array_u8_Sentinel0, "base", self.ptr_otherwise).len,
|
||||
.array_u8_sentinel_0 => @fieldParentPtr(Payload.Array_u8_Sentinel0, "base", self.ptr_otherwise).len + 1,
|
||||
.array => {
|
||||
const payload = @fieldParentPtr(Payload.Array, "base", self.ptr_otherwise);
|
||||
const elem_size = std.math.max(payload.elem_type.abiAlignment(target), payload.elem_type.abiSize(target));
|
||||
return payload.len * elem_size;
|
||||
},
|
||||
.array_sentinel => {
|
||||
const payload = @fieldParentPtr(Payload.ArraySentinel, "base", self.ptr_otherwise);
|
||||
const elem_size = std.math.max(payload.elem_type.abiAlignment(target), payload.elem_type.abiSize(target));
|
||||
return (payload.len + 1) * elem_size;
|
||||
},
|
||||
.i16, .u16 => return 2,
|
||||
.i32, .u32 => return 4,
|
||||
.i64, .u64 => return 8,
|
||||
@ -818,6 +849,8 @@ pub const Type = extern union {
|
||||
.@"null",
|
||||
.@"undefined",
|
||||
.array,
|
||||
.array_sentinel,
|
||||
.array_u8,
|
||||
.array_u8_sentinel_0,
|
||||
.const_slice_u8,
|
||||
.fn_noreturn_no_args,
|
||||
@ -875,6 +908,8 @@ pub const Type = extern union {
|
||||
.@"null",
|
||||
.@"undefined",
|
||||
.array,
|
||||
.array_sentinel,
|
||||
.array_u8,
|
||||
.array_u8_sentinel_0,
|
||||
.single_const_pointer,
|
||||
.single_mut_pointer,
|
||||
@ -931,6 +966,8 @@ pub const Type = extern union {
|
||||
.@"null",
|
||||
.@"undefined",
|
||||
.array,
|
||||
.array_sentinel,
|
||||
.array_u8,
|
||||
.array_u8_sentinel_0,
|
||||
.fn_noreturn_no_args,
|
||||
.fn_void_no_args,
|
||||
@ -988,6 +1025,8 @@ pub const Type = extern union {
|
||||
.@"null",
|
||||
.@"undefined",
|
||||
.array,
|
||||
.array_sentinel,
|
||||
.array_u8,
|
||||
.array_u8_sentinel_0,
|
||||
.fn_noreturn_no_args,
|
||||
.fn_void_no_args,
|
||||
@ -1072,9 +1111,10 @@ pub const Type = extern union {
|
||||
=> unreachable,
|
||||
|
||||
.array => self.cast(Payload.Array).?.elem_type,
|
||||
.array_sentinel => self.cast(Payload.ArraySentinel).?.elem_type,
|
||||
.single_const_pointer => self.castPointer().?.pointee_type,
|
||||
.single_mut_pointer => self.castPointer().?.pointee_type,
|
||||
.array_u8_sentinel_0, .const_slice_u8 => Type.initTag(.u8),
|
||||
.array_u8, .array_u8_sentinel_0, .const_slice_u8 => Type.initTag(.u8),
|
||||
.single_const_pointer_to_comptime_int => Type.initTag(.comptime_int),
|
||||
};
|
||||
}
|
||||
@ -1176,6 +1216,8 @@ pub const Type = extern union {
|
||||
=> unreachable,
|
||||
|
||||
.array => self.cast(Payload.Array).?.len,
|
||||
.array_sentinel => self.cast(Payload.ArraySentinel).?.len,
|
||||
.array_u8 => self.cast(Payload.Array_u8).?.len,
|
||||
.array_u8_sentinel_0 => self.cast(Payload.Array_u8_Sentinel0).?.len,
|
||||
};
|
||||
}
|
||||
@ -1232,7 +1274,8 @@ pub const Type = extern union {
|
||||
.optional_single_const_pointer,
|
||||
=> unreachable,
|
||||
|
||||
.array => return null,
|
||||
.array, .array_u8 => return null,
|
||||
.array_sentinel => return self.cast(Payload.ArraySentinel).?.sentinel,
|
||||
.array_u8_sentinel_0 => return Value.initTag(.zero),
|
||||
};
|
||||
}
|
||||
@ -1266,10 +1309,12 @@ pub const Type = extern union {
|
||||
.fn_ccc_void_no_args,
|
||||
.function,
|
||||
.array,
|
||||
.array_sentinel,
|
||||
.array_u8,
|
||||
.array_u8_sentinel_0,
|
||||
.single_const_pointer,
|
||||
.single_mut_pointer,
|
||||
.single_const_pointer_to_comptime_int,
|
||||
.array_u8_sentinel_0,
|
||||
.const_slice_u8,
|
||||
.int_unsigned,
|
||||
.u8,
|
||||
@ -1324,10 +1369,12 @@ pub const Type = extern union {
|
||||
.fn_ccc_void_no_args,
|
||||
.function,
|
||||
.array,
|
||||
.array_sentinel,
|
||||
.array_u8,
|
||||
.array_u8_sentinel_0,
|
||||
.single_const_pointer,
|
||||
.single_mut_pointer,
|
||||
.single_const_pointer_to_comptime_int,
|
||||
.array_u8_sentinel_0,
|
||||
.const_slice_u8,
|
||||
.int_signed,
|
||||
.i8,
|
||||
@ -1382,10 +1429,12 @@ pub const Type = extern union {
|
||||
.fn_ccc_void_no_args,
|
||||
.function,
|
||||
.array,
|
||||
.array_sentinel,
|
||||
.array_u8,
|
||||
.array_u8_sentinel_0,
|
||||
.single_const_pointer,
|
||||
.single_mut_pointer,
|
||||
.single_const_pointer_to_comptime_int,
|
||||
.array_u8_sentinel_0,
|
||||
.const_slice_u8,
|
||||
.optional,
|
||||
.optional_single_mut_pointer,
|
||||
@ -1438,10 +1487,12 @@ pub const Type = extern union {
|
||||
.fn_ccc_void_no_args,
|
||||
.function,
|
||||
.array,
|
||||
.array_sentinel,
|
||||
.array_u8,
|
||||
.array_u8_sentinel_0,
|
||||
.single_const_pointer,
|
||||
.single_mut_pointer,
|
||||
.single_const_pointer_to_comptime_int,
|
||||
.array_u8_sentinel_0,
|
||||
.const_slice_u8,
|
||||
.int_unsigned,
|
||||
.int_signed,
|
||||
@ -1523,10 +1574,12 @@ pub const Type = extern union {
|
||||
.@"null",
|
||||
.@"undefined",
|
||||
.array,
|
||||
.array_sentinel,
|
||||
.array_u8,
|
||||
.array_u8_sentinel_0,
|
||||
.single_const_pointer,
|
||||
.single_mut_pointer,
|
||||
.single_const_pointer_to_comptime_int,
|
||||
.array_u8_sentinel_0,
|
||||
.const_slice_u8,
|
||||
.u8,
|
||||
.i8,
|
||||
@ -1584,10 +1637,12 @@ pub const Type = extern union {
|
||||
.@"null",
|
||||
.@"undefined",
|
||||
.array,
|
||||
.array_sentinel,
|
||||
.array_u8,
|
||||
.array_u8_sentinel_0,
|
||||
.single_const_pointer,
|
||||
.single_mut_pointer,
|
||||
.single_const_pointer_to_comptime_int,
|
||||
.array_u8_sentinel_0,
|
||||
.const_slice_u8,
|
||||
.u8,
|
||||
.i8,
|
||||
@ -1644,10 +1699,12 @@ pub const Type = extern union {
|
||||
.@"null",
|
||||
.@"undefined",
|
||||
.array,
|
||||
.array_sentinel,
|
||||
.array_u8,
|
||||
.array_u8_sentinel_0,
|
||||
.single_const_pointer,
|
||||
.single_mut_pointer,
|
||||
.single_const_pointer_to_comptime_int,
|
||||
.array_u8_sentinel_0,
|
||||
.const_slice_u8,
|
||||
.u8,
|
||||
.i8,
|
||||
@ -1704,10 +1761,12 @@ pub const Type = extern union {
|
||||
.@"null",
|
||||
.@"undefined",
|
||||
.array,
|
||||
.array_sentinel,
|
||||
.array_u8,
|
||||
.array_u8_sentinel_0,
|
||||
.single_const_pointer,
|
||||
.single_mut_pointer,
|
||||
.single_const_pointer_to_comptime_int,
|
||||
.array_u8_sentinel_0,
|
||||
.const_slice_u8,
|
||||
.u8,
|
||||
.i8,
|
||||
@ -1761,10 +1820,12 @@ pub const Type = extern union {
|
||||
.@"null",
|
||||
.@"undefined",
|
||||
.array,
|
||||
.array_sentinel,
|
||||
.array_u8,
|
||||
.array_u8_sentinel_0,
|
||||
.single_const_pointer,
|
||||
.single_mut_pointer,
|
||||
.single_const_pointer_to_comptime_int,
|
||||
.array_u8_sentinel_0,
|
||||
.const_slice_u8,
|
||||
.u8,
|
||||
.i8,
|
||||
@ -1818,10 +1879,12 @@ pub const Type = extern union {
|
||||
.@"null",
|
||||
.@"undefined",
|
||||
.array,
|
||||
.array_sentinel,
|
||||
.array_u8,
|
||||
.array_u8_sentinel_0,
|
||||
.single_const_pointer,
|
||||
.single_mut_pointer,
|
||||
.single_const_pointer_to_comptime_int,
|
||||
.array_u8_sentinel_0,
|
||||
.const_slice_u8,
|
||||
.u8,
|
||||
.i8,
|
||||
@ -1895,10 +1958,12 @@ pub const Type = extern union {
|
||||
.fn_ccc_void_no_args,
|
||||
.function,
|
||||
.array,
|
||||
.array_sentinel,
|
||||
.array_u8,
|
||||
.array_u8_sentinel_0,
|
||||
.single_const_pointer,
|
||||
.single_mut_pointer,
|
||||
.single_const_pointer_to_comptime_int,
|
||||
.array_u8_sentinel_0,
|
||||
.const_slice_u8,
|
||||
.optional,
|
||||
.optional_single_mut_pointer,
|
||||
@ -1944,6 +2009,7 @@ pub const Type = extern union {
|
||||
.fn_ccc_void_no_args,
|
||||
.function,
|
||||
.single_const_pointer_to_comptime_int,
|
||||
.array_sentinel,
|
||||
.array_u8_sentinel_0,
|
||||
.const_slice_u8,
|
||||
.c_void,
|
||||
@ -1971,11 +2037,10 @@ pub const Type = extern union {
|
||||
return null;
|
||||
}
|
||||
},
|
||||
.array => {
|
||||
const array = ty.cast(Payload.Array).?;
|
||||
if (array.len == 0)
|
||||
.array, .array_u8 => {
|
||||
if (ty.arrayLen() == 0)
|
||||
return Value.initTag(.empty_array);
|
||||
ty = array.elem_type;
|
||||
ty = ty.elemType();
|
||||
continue;
|
||||
},
|
||||
.single_const_pointer, .single_mut_pointer => {
|
||||
@ -2022,7 +2087,6 @@ pub const Type = extern union {
|
||||
.fn_ccc_void_no_args,
|
||||
.function,
|
||||
.single_const_pointer_to_comptime_int,
|
||||
.array_u8_sentinel_0,
|
||||
.const_slice_u8,
|
||||
.c_void,
|
||||
.void,
|
||||
@ -2032,6 +2096,9 @@ pub const Type = extern union {
|
||||
.int_unsigned,
|
||||
.int_signed,
|
||||
.array,
|
||||
.array_sentinel,
|
||||
.array_u8,
|
||||
.array_u8_sentinel_0,
|
||||
.single_const_pointer,
|
||||
.single_mut_pointer,
|
||||
.optional,
|
||||
@ -2090,8 +2157,10 @@ pub const Type = extern union {
|
||||
const_slice_u8, // See last_no_payload_tag below.
|
||||
// After this, the tag requires a payload.
|
||||
|
||||
array_u8,
|
||||
array_u8_sentinel_0,
|
||||
array,
|
||||
array_sentinel,
|
||||
single_const_pointer,
|
||||
single_mut_pointer,
|
||||
int_signed,
|
||||
@ -2114,11 +2183,25 @@ pub const Type = extern union {
|
||||
len: u64,
|
||||
};
|
||||
|
||||
pub const Array_u8 = struct {
|
||||
base: Payload = Payload{ .tag = .array_u8 },
|
||||
|
||||
len: u64,
|
||||
};
|
||||
|
||||
pub const Array = struct {
|
||||
base: Payload = Payload{ .tag = .array },
|
||||
|
||||
elem_type: Type,
|
||||
len: u64,
|
||||
elem_type: Type,
|
||||
};
|
||||
|
||||
pub const ArraySentinel = struct {
|
||||
base: Payload = Payload{ .tag = .array_sentinel },
|
||||
|
||||
len: u64,
|
||||
sentinel: Value,
|
||||
elem_type: Type,
|
||||
};
|
||||
|
||||
pub const Pointer = struct {
|
||||
|
@ -47,6 +47,10 @@ pub const Inst = struct {
|
||||
array_cat,
|
||||
/// Array multiplication `a ** b`
|
||||
array_mul,
|
||||
/// Create an array type
|
||||
array_type,
|
||||
/// Create an array type with sentinel
|
||||
array_type_sentinel,
|
||||
/// Function parameter value. These must be first in a function's main block,
|
||||
/// in respective order with the parameters.
|
||||
arg,
|
||||
@ -268,6 +272,7 @@ pub const Inst = struct {
|
||||
.addwrap,
|
||||
.array_cat,
|
||||
.array_mul,
|
||||
.array_type,
|
||||
.bitand,
|
||||
.bitor,
|
||||
.div,
|
||||
@ -294,6 +299,7 @@ pub const Inst = struct {
|
||||
=> BinOp,
|
||||
|
||||
.arg => Arg,
|
||||
.array_type_sentinel => ArrayTypeSentinel,
|
||||
.block => Block,
|
||||
.@"break" => Break,
|
||||
.breakvoid => BreakVoid,
|
||||
@ -333,6 +339,8 @@ pub const Inst = struct {
|
||||
.alloc_inferred,
|
||||
.array_cat,
|
||||
.array_mul,
|
||||
.array_type,
|
||||
.array_type_sentinel,
|
||||
.arg,
|
||||
.as,
|
||||
.@"asm",
|
||||
@ -849,6 +857,18 @@ pub const Inst = struct {
|
||||
sentinel: ?*Inst = null,
|
||||
},
|
||||
};
|
||||
|
||||
pub const ArrayTypeSentinel = struct {
|
||||
pub const base_tag = Tag.array_type_sentinel;
|
||||
base: Inst,
|
||||
|
||||
positionals: struct {
|
||||
len: *Inst,
|
||||
sentinel: *Inst,
|
||||
elem_type: *Inst,
|
||||
},
|
||||
kw_args: struct {},
|
||||
};
|
||||
};
|
||||
|
||||
pub const ErrorMsg = struct {
|
||||
|
@ -113,6 +113,8 @@ pub fn analyzeInst(mod: *Module, scope: *Scope, old_inst: *zir.Inst) InnerError!
|
||||
.unwrap_err_safe => return analyzeInstUnwrapErr(mod, scope, old_inst.castTag(.unwrap_err_safe).?, true),
|
||||
.unwrap_err_unsafe => return analyzeInstUnwrapErr(mod, scope, old_inst.castTag(.unwrap_err_unsafe).?, false),
|
||||
.ensure_err_payload_void => return analyzeInstEnsureErrPayloadVoid(mod, scope, old_inst.castTag(.ensure_err_payload_void).?),
|
||||
.array_type => return analyzeInstArrayType(mod, scope, old_inst.castTag(.array_type).?),
|
||||
.array_type_sentinel => return analyzeInstArrayTypeSentinel(mod, scope, old_inst.castTag(.array_type_sentinel).?),
|
||||
}
|
||||
}
|
||||
|
||||
@ -676,31 +678,24 @@ fn analyzeInstIntType(mod: *Module, scope: *Scope, inttype: *zir.Inst.IntType) I
|
||||
fn analyzeInstOptionalType(mod: *Module, scope: *Scope, optional: *zir.Inst.UnOp) InnerError!*Inst {
|
||||
const child_type = try resolveType(mod, scope, optional.positionals.operand);
|
||||
|
||||
return mod.constType(scope, optional.base.src, Type.initPayload(switch (child_type.tag()) {
|
||||
.single_const_pointer => blk: {
|
||||
const payload = try scope.arena().create(Type.Payload.Pointer);
|
||||
payload.* = .{
|
||||
.base = .{ .tag = .optional_single_const_pointer },
|
||||
.pointee_type = child_type.elemType(),
|
||||
};
|
||||
break :blk &payload.base;
|
||||
},
|
||||
.single_mut_pointer => blk: {
|
||||
const payload = try scope.arena().create(Type.Payload.Pointer);
|
||||
payload.* = .{
|
||||
.base = .{ .tag = .optional_single_mut_pointer },
|
||||
.pointee_type = child_type.elemType(),
|
||||
};
|
||||
break :blk &payload.base;
|
||||
},
|
||||
else => blk: {
|
||||
const payload = try scope.arena().create(Type.Payload.Optional);
|
||||
payload.* = .{
|
||||
.child_type = child_type,
|
||||
};
|
||||
break :blk &payload.base;
|
||||
},
|
||||
}));
|
||||
return mod.constType(scope, optional.base.src, try mod.optionalType(scope, child_type));
|
||||
}
|
||||
|
||||
fn analyzeInstArrayType(mod: *Module, scope: *Scope, array: *zir.Inst.BinOp) InnerError!*Inst {
|
||||
// TODO these should be lazily evaluated
|
||||
const len = try resolveInstConst(mod, scope, array.positionals.lhs);
|
||||
const elem_type = try resolveType(mod, scope, array.positionals.rhs);
|
||||
|
||||
return mod.constType(scope, array.base.src, try mod.arrayType(scope, len.val.toUnsignedInt(), null, elem_type));
|
||||
}
|
||||
|
||||
fn analyzeInstArrayTypeSentinel(mod: *Module, scope: *Scope, array: *zir.Inst.ArrayTypeSentinel) InnerError!*Inst {
|
||||
// TODO these should be lazily evaluated
|
||||
const len = try resolveInstConst(mod, scope, array.positionals.len);
|
||||
const sentinel = try resolveInstConst(mod, scope, array.positionals.sentinel);
|
||||
const elem_type = try resolveType(mod, scope, array.positionals.elem_type);
|
||||
|
||||
return mod.constType(scope, array.base.src, try mod.arrayType(scope, len.val.toUnsignedInt(), sentinel.val, elem_type));
|
||||
}
|
||||
|
||||
fn analyzeInstUnwrapOptional(mod: *Module, scope: *Scope, unwrap: *zir.Inst.UnOp, safety_check: bool) InnerError!*Inst {
|
||||
|
Loading…
Reference in New Issue
Block a user