mirror of
https://github.com/ziglang/zig.git
synced 2026-02-12 20:37:54 +00:00
stage2: implement Sema for elemVal for comptime slice
This commit is contained in:
parent
e851d89113
commit
da7fcfd158
15
src/Sema.zig
15
src/Sema.zig
@ -11048,11 +11048,16 @@ fn elemVal(
|
||||
switch (maybe_ptr_ty.zigTypeTag()) {
|
||||
.Pointer => switch (maybe_ptr_ty.ptrSize()) {
|
||||
.Slice => {
|
||||
if (try sema.resolveDefinedValue(block, src, array_maybe_ptr)) |slice_val| {
|
||||
_ = slice_val;
|
||||
return sema.fail(block, src, "TODO implement Sema for elemVal for comptime known slice", .{});
|
||||
}
|
||||
try sema.requireRuntimeBlock(block, src);
|
||||
const maybe_slice_val = try sema.resolveDefinedValue(block, array_ptr_src, array_maybe_ptr);
|
||||
const maybe_index_val = try sema.resolveDefinedValue(block, elem_index_src, elem_index);
|
||||
const runtime_src = if (maybe_slice_val) |slice_val| rs: {
|
||||
const index_val = maybe_index_val orelse break :rs elem_index_src;
|
||||
const index = @intCast(usize, index_val.toUnsignedInt());
|
||||
const elem_val = try slice_val.elemValue(sema.arena, index);
|
||||
return sema.addConstant(maybe_ptr_ty.elemType2(), elem_val);
|
||||
} else array_ptr_src;
|
||||
|
||||
try sema.requireRuntimeBlock(block, runtime_src);
|
||||
return block.addBinOp(.slice_elem_val, array_maybe_ptr, elem_index);
|
||||
},
|
||||
.Many, .C => {
|
||||
|
||||
@ -2448,6 +2448,7 @@ pub const Type = extern union {
|
||||
/// For ?[*]T, returns T.
|
||||
/// For *T, returns T.
|
||||
/// For [*]T, returns T.
|
||||
/// For []T, returns T.
|
||||
pub fn elemType2(ty: Type) Type {
|
||||
return switch (ty.tag()) {
|
||||
.vector => ty.castTag(.vector).?.data.elem_type,
|
||||
|
||||
@ -1651,6 +1651,9 @@ pub const Value = extern union {
|
||||
.array => return val.castTag(.array).?.data[index],
|
||||
.slice => return val.castTag(.slice).?.data.ptr.elemValue(arena, index),
|
||||
|
||||
.decl_ref => return val.castTag(.decl_ref).?.data.val.elemValue(arena, index),
|
||||
.decl_ref_mut => return val.castTag(.decl_ref_mut).?.data.decl.val.elemValue(arena, index),
|
||||
|
||||
else => unreachable,
|
||||
}
|
||||
}
|
||||
|
||||
@ -3,3 +3,24 @@ const expect = std.testing.expect;
|
||||
const expectEqualSlices = std.testing.expectEqualSlices;
|
||||
const expectEqual = std.testing.expectEqual;
|
||||
const mem = std.mem;
|
||||
|
||||
// comptime array passed as slice argument
|
||||
comptime {
|
||||
const S = struct {
|
||||
fn indexOfScalarPos(comptime T: type, slice: []const T, start_index: usize, value: T) ?usize {
|
||||
var i: usize = start_index;
|
||||
while (i < slice.len) : (i += 1) {
|
||||
if (slice[i] == value) return i;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
fn indexOfScalar(comptime T: type, slice: []const T, value: T) ?usize {
|
||||
return indexOfScalarPos(T, slice, 0, value);
|
||||
}
|
||||
};
|
||||
const unsigned = [_]type{ c_uint, c_ulong, c_ulonglong };
|
||||
const list: []const type = &unsigned;
|
||||
var pos = S.indexOfScalar(type, list, c_ulong).?;
|
||||
if (pos != 1) @compileError("bad pos");
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user