feature. See also
. The project being documented here (as the example) is the Zig library itself.
Translator.transArrayAccess
fn transArrayAccess(t: *Translator, scope: *Scope, array_access: Node.ArrayAccess, opt_base: ?ZigNode) TransError!ZigNode
File
Code
fn transArrayAccess(t: *Translator, scope: *Scope, array_access: Node.ArrayAccess, opt_base: ?ZigNode) TransError!ZigNode {
// so that we index the array itself
const base = base: {
const base = array_access.base.get(t.tree);
if (base != .cast) break :base array_access.base;
if (base.cast.kind != .array_to_pointer) break :base array_access.base;
break :base base.cast.operand;
};
const base_node = opt_base orelse try t.transExpr(scope, base, .used);
const index = index: {
const index = try t.transExpr(scope, array_access.index, .used);
const index_qt = array_access.index.qt(t.tree);
const maybe_bigger_than_usize = type: switch (index_qt.base(t.comp).type) {
.bool => {
break :index try ZigTag.int_from_bool.create(t.arena, index);
},
.int => |int| switch (int) {
.long_long, .ulong_long, .int128, .uint128 => true,
else => false,
},
.bit_int => |bit_int| bit_int.bits > t.comp.target.ptrBitWidth(),
.@"enum" => |e| if (e.tag) |tag| continue :type tag.base(t.comp).type else false,
else => unreachable,
};
const is_nonnegative_int_literal = if (t.tree.value_map.get(array_access.index)) |val|
val.compare(.gte, .zero, t.comp)
else
false;
const is_signed = t.signedness(index_qt) == .signed;
if (is_signed and !is_nonnegative_int_literal) {
// then @bitCast to `usize` to satisfy the compiler.
const index_isize = try ZigTag.as.create(t.arena, .{
.lhs = try ZigTag.type.create(t.arena, "isize"),
.rhs = try ZigTag.int_cast.create(t.arena, index),
});
break :index try ZigTag.bit_cast.create(t.arena, index_isize);
}
if (maybe_bigger_than_usize) {
break :index try ZigTag.int_cast.create(t.arena, index);
}
break :index index;
};
return ZigTag.array_access.create(t.arena, .{
.lhs = base_node,
.rhs = index,
});
}