mirror of
https://github.com/ziglang/zig.git
synced 2026-01-21 06:45:24 +00:00
stage2: array access astgen
This commit is contained in:
parent
bcd04089eb
commit
bf014d529a
@ -274,6 +274,7 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node) InnerEr
|
||||
.ErrorSetDecl => return errorSetDecl(mod, scope, rl, node.castTag(.ErrorSetDecl).?),
|
||||
.ErrorType => return rlWrap(mod, scope, rl, try errorType(mod, scope, node.castTag(.ErrorType).?)),
|
||||
.For => return forExpr(mod, scope, rl, node.castTag(.For).?),
|
||||
.ArrayAccess => return arrayAccess(mod, scope, rl, node.castTag(.ArrayAccess).?),
|
||||
|
||||
.Defer => return mod.failNode(scope, node, "TODO implement astgen.expr for .Defer", .{}),
|
||||
.Catch => return mod.failNode(scope, node, "TODO implement astgen.expr for .Catch", .{}),
|
||||
@ -283,7 +284,6 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node) InnerEr
|
||||
.Resume => return mod.failNode(scope, node, "TODO implement astgen.expr for .Resume", .{}),
|
||||
.Try => return mod.failNode(scope, node, "TODO implement astgen.expr for .Try", .{}),
|
||||
.Slice => return mod.failNode(scope, node, "TODO implement astgen.expr for .Slice", .{}),
|
||||
.ArrayAccess => return mod.failNode(scope, node, "TODO implement astgen.expr for .ArrayAccess", .{}),
|
||||
.ArrayInitializer => return mod.failNode(scope, node, "TODO implement astgen.expr for .ArrayInitializer", .{}),
|
||||
.ArrayInitializerDot => return mod.failNode(scope, node, "TODO implement astgen.expr for .ArrayInitializerDot", .{}),
|
||||
.StructInitializer => return mod.failNode(scope, node, "TODO implement astgen.expr for .StructInitializer", .{}),
|
||||
@ -797,6 +797,16 @@ fn field(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.SimpleInfix
|
||||
return rlWrapPtr(mod, scope, rl, try addZIRInst(mod, scope, src, zir.Inst.FieldPtr, .{ .object_ptr = lhs, .field_name = field_name }, .{}));
|
||||
}
|
||||
|
||||
fn arrayAccess(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.ArrayAccess) InnerError!*zir.Inst {
|
||||
const tree = scope.tree();
|
||||
const src = tree.token_locs[node.rtoken].start;
|
||||
|
||||
const array_ptr = try expr(mod, scope, .ref, node.lhs);
|
||||
const index = try expr(mod, scope, .none, node.index_expr);
|
||||
|
||||
return rlWrapPtr(mod, scope, rl, try addZIRInst(mod, scope, src, zir.Inst.ElemPtr, .{ .array_ptr = array_ptr, .index = index }, .{}));
|
||||
}
|
||||
|
||||
fn deref(mod: *Module, scope: *Scope, node: *ast.Node.SimpleSuffixOp) InnerError!*zir.Inst {
|
||||
const tree = scope.tree();
|
||||
const src = tree.token_locs[node.rtoken].start;
|
||||
|
||||
@ -1076,9 +1076,19 @@ fn analyzeInstElemPtr(mod: *Module, scope: *Scope, inst: *zir.Inst.ElemPtr) Inne
|
||||
const array_ptr = try resolveInst(mod, scope, inst.positionals.array_ptr);
|
||||
const uncasted_index = try resolveInst(mod, scope, inst.positionals.index);
|
||||
const elem_index = try mod.coerce(scope, Type.initTag(.usize), uncasted_index);
|
||||
|
||||
const elem_ty = switch (array_ptr.ty.zigTypeTag()) {
|
||||
.Pointer => array_ptr.ty.elemType(),
|
||||
else => return mod.fail(scope, inst.positionals.array_ptr.src, "expected pointer, found '{}'", .{array_ptr.ty}),
|
||||
};
|
||||
if (!elem_ty.isIndexable()) {
|
||||
return mod.fail(scope, inst.base.src, "array access of non-array type '{}'", .{elem_ty});
|
||||
}
|
||||
|
||||
if (array_ptr.ty.isSinglePointer() and array_ptr.ty.elemType().zigTypeTag() == .Array) {
|
||||
if (array_ptr.value()) |array_ptr_val| {
|
||||
if (elem_ty.isSinglePointer() and elem_ty.elemType().zigTypeTag() == .Array) {
|
||||
// we have to deref the ptr operand to get the actual array pointer
|
||||
const array_ptr_deref = try mod.analyzeDeref(scope, inst.base.src, array_ptr, inst.positionals.array_ptr.src);
|
||||
if (array_ptr_deref.value()) |array_ptr_val| {
|
||||
if (elem_index.value()) |index_val| {
|
||||
// Both array pointer and index are compile-time known.
|
||||
const index_u64 = index_val.toUnsignedInt();
|
||||
@ -1089,7 +1099,7 @@ fn analyzeInstElemPtr(mod: *Module, scope: *Scope, inst: *zir.Inst.ElemPtr) Inne
|
||||
const type_payload = try scope.arena().create(Type.Payload.PointerSimple);
|
||||
type_payload.* = .{
|
||||
.base = .{ .tag = .single_const_pointer },
|
||||
.pointee_type = array_ptr.ty.elemType().elemType(),
|
||||
.pointee_type = elem_ty.elemType().elemType(),
|
||||
};
|
||||
|
||||
return mod.constInst(scope, inst.base.src, .{
|
||||
|
||||
@ -820,6 +820,31 @@ pub fn addCases(ctx: *TestContext) !void {
|
||||
,
|
||||
"",
|
||||
);
|
||||
|
||||
// Array access.
|
||||
case.addCompareOutput(
|
||||
\\export fn _start() noreturn {
|
||||
\\ assert("hello"[0] == 'h');
|
||||
\\
|
||||
\\ exit();
|
||||
\\}
|
||||
\\
|
||||
\\pub fn assert(ok: bool) void {
|
||||
\\ if (!ok) unreachable; // assertion failure
|
||||
\\}
|
||||
\\
|
||||
\\fn exit() noreturn {
|
||||
\\ asm volatile ("syscall"
|
||||
\\ :
|
||||
\\ : [number] "{rax}" (231),
|
||||
\\ [arg1] "{rdi}" (0)
|
||||
\\ : "rcx", "r11", "memory"
|
||||
\\ );
|
||||
\\ unreachable;
|
||||
\\}
|
||||
,
|
||||
"",
|
||||
);
|
||||
}
|
||||
|
||||
{
|
||||
|
||||
@ -43,10 +43,11 @@ pub fn addCases(ctx: *TestContext) !void {
|
||||
\\
|
||||
\\@entry = fn(@fnty, {
|
||||
\\ %a = str("\x32\x08\x01\x0a")
|
||||
\\ %eptr0 = elemptr(%a, @0)
|
||||
\\ %eptr1 = elemptr(%a, @1)
|
||||
\\ %eptr2 = elemptr(%a, @2)
|
||||
\\ %eptr3 = elemptr(%a, @3)
|
||||
\\ %a_ref = ref(%a)
|
||||
\\ %eptr0 = elemptr(%a_ref, @0)
|
||||
\\ %eptr1 = elemptr(%a_ref, @1)
|
||||
\\ %eptr2 = elemptr(%a_ref, @2)
|
||||
\\ %eptr3 = elemptr(%a_ref, @3)
|
||||
\\ %v0 = deref(%eptr0)
|
||||
\\ %v1 = deref(%eptr1)
|
||||
\\ %v2 = deref(%eptr2)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user