authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-10-13 16:31:07-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-10-13 16:31:07-07:00
logda7fcfd1586fa93c3d00815f60030e00ea583701
treed1f9b47a50df7ebff0b43a5ca98a406149821ddf
parente851d89113a57064c38ed85722edc7f686d0c11a

stage2: implement Sema for elemVal for comptime slice


4 files changed, 35 insertions(+), 5 deletions(-)

src/Sema.zig+10-5
...@@ -11048,11 +11048,16 @@ fn elemVal(...@@ -11048,11 +11048,16 @@ fn elemVal(
11048 switch (maybe_ptr_ty.zigTypeTag()) {11048 switch (maybe_ptr_ty.zigTypeTag()) {
11049 .Pointer => switch (maybe_ptr_ty.ptrSize()) {11049 .Pointer => switch (maybe_ptr_ty.ptrSize()) {
11050 .Slice => {11050 .Slice => {
11051 if (try sema.resolveDefinedValue(block, src, array_maybe_ptr)) |slice_val| {11051 const maybe_slice_val = try sema.resolveDefinedValue(block, array_ptr_src, array_maybe_ptr);
11052 _ = slice_val;11052 const maybe_index_val = try sema.resolveDefinedValue(block, elem_index_src, elem_index);
11053 return sema.fail(block, src, "TODO implement Sema for elemVal for comptime known slice", .{});11053 const runtime_src = if (maybe_slice_val) |slice_val| rs: {
11054 }11054 const index_val = maybe_index_val orelse break :rs elem_index_src;
11055 try sema.requireRuntimeBlock(block, src);11055 const index = @intCast(usize, index_val.toUnsignedInt());
11056 const elem_val = try slice_val.elemValue(sema.arena, index);
11057 return sema.addConstant(maybe_ptr_ty.elemType2(), elem_val);
11058 } else array_ptr_src;
11059
11060 try sema.requireRuntimeBlock(block, runtime_src);
11056 return block.addBinOp(.slice_elem_val, array_maybe_ptr, elem_index);11061 return block.addBinOp(.slice_elem_val, array_maybe_ptr, elem_index);
11057 },11062 },
11058 .Many, .C => {11063 .Many, .C => {
src/type.zig+1
...@@ -2448,6 +2448,7 @@ pub const Type = extern union {...@@ -2448,6 +2448,7 @@ pub const Type = extern union {
2448 /// For ?[*]T, returns T.2448 /// For ?[*]T, returns T.
2449 /// For *T, returns T.2449 /// For *T, returns T.
2450 /// For [*]T, returns T.2450 /// For [*]T, returns T.
2451 /// For []T, returns T.
2451 pub fn elemType2(ty: Type) Type {2452 pub fn elemType2(ty: Type) Type {
2452 return switch (ty.tag()) {2453 return switch (ty.tag()) {
2453 .vector => ty.castTag(.vector).?.data.elem_type,2454 .vector => ty.castTag(.vector).?.data.elem_type,
src/value.zig+3
...@@ -1651,6 +1651,9 @@ pub const Value = extern union {...@@ -1651,6 +1651,9 @@ pub const Value = extern union {
1651 .array => return val.castTag(.array).?.data[index],1651 .array => return val.castTag(.array).?.data[index],
1652 .slice => return val.castTag(.slice).?.data.ptr.elemValue(arena, index),1652 .slice => return val.castTag(.slice).?.data.ptr.elemValue(arena, index),
16531653
1654 .decl_ref => return val.castTag(.decl_ref).?.data.val.elemValue(arena, index),
1655 .decl_ref_mut => return val.castTag(.decl_ref_mut).?.data.decl.val.elemValue(arena, index),
1656
1654 else => unreachable,1657 else => unreachable,
1655 }1658 }
1656 }1659 }
test/behavior/slice.zig+21
...@@ -3,3 +3,24 @@ const expect = std.testing.expect;...@@ -3,3 +3,24 @@ const expect = std.testing.expect;
3const expectEqualSlices = std.testing.expectEqualSlices;3const expectEqualSlices = std.testing.expectEqualSlices;
4const expectEqual = std.testing.expectEqual;4const expectEqual = std.testing.expectEqual;
5const mem = std.mem;5const mem = std.mem;
6
7// comptime array passed as slice argument
8comptime {
9 const S = struct {
10 fn indexOfScalarPos(comptime T: type, slice: []const T, start_index: usize, value: T) ?usize {
11 var i: usize = start_index;
12 while (i < slice.len) : (i += 1) {
13 if (slice[i] == value) return i;
14 }
15 return null;
16 }
17
18 fn indexOfScalar(comptime T: type, slice: []const T, value: T) ?usize {
19 return indexOfScalarPos(T, slice, 0, value);
20 }
21 };
22 const unsigned = [_]type{ c_uint, c_ulong, c_ulonglong };
23 const list: []const type = &unsigned;
24 var pos = S.indexOfScalar(type, list, c_ulong).?;
25 if (pos != 1) @compileError("bad pos");
26}