From a72bfd00cf07da50a94a024d6f74167aa41382c5 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Fri, 26 Mar 2021 18:26:39 -0700 Subject: [PATCH] astgen: fix continue expressions --- src/astgen.zig | 18 ++--- test/stage2/test.zig | 178 +++++++++++++++++++++---------------------- 2 files changed, 97 insertions(+), 99 deletions(-) diff --git a/src/astgen.zig b/src/astgen.zig index 664a37c9d1..d01bc46515 100644 --- a/src/astgen.zig +++ b/src/astgen.zig @@ -766,11 +766,9 @@ fn breakExpr(mod: *Module, parent_scope: *Scope, node: ast.Node.Index) InnerErro } fn continueExpr(mod: *Module, parent_scope: *Scope, node: ast.Node.Index) InnerError!zir.Inst.Ref { - if (true) @panic("TODO update for zir-memory-layout"); - const tree = parent_scope.tree(); + const parent_gz = parent_scope.getGenZir(); + const tree = parent_gz.tree(); const node_datas = tree.nodes.items(.data); - const main_tokens = tree.nodes.items(.main_token); - const break_label = node_datas[node].lhs; // Look for the label in the scope. @@ -779,10 +777,11 @@ fn continueExpr(mod: *Module, parent_scope: *Scope, node: ast.Node.Index) InnerE switch (scope.tag) { .gen_zir => { const gen_zir = scope.cast(Scope.GenZir).?; - const continue_block = gen_zir.continue_block orelse { + const continue_block = gen_zir.continue_block; + if (continue_block == 0) { scope = gen_zir.parent; continue; - }; + } if (break_label != 0) blk: { if (gen_zir.label) |*label| { if (try tokenIdentEql(mod, parent_scope, label.token, break_label)) { @@ -795,9 +794,8 @@ fn continueExpr(mod: *Module, parent_scope: *Scope, node: ast.Node.Index) InnerE continue; } - _ = try addZirInstTag(mod, parent_scope, src, .break_void, .{ - .block = continue_block, - }); + // TODO emit a break_inline if the loop being continued is inline + _ = try parent_gz.addBreak(.@"break", continue_block, .void_value); return zir.Inst.Ref.unreachable_value; }, .local_val => scope = scope.cast(Scope.LocalVal).?.parent, @@ -806,7 +804,7 @@ fn continueExpr(mod: *Module, parent_scope: *Scope, node: ast.Node.Index) InnerE const label_name = try mod.identifierTokenString(parent_scope, break_label); return mod.failTok(parent_scope, break_label, "label not found: '{s}'", .{label_name}); } else { - return mod.failTok(parent_scope, src, "continue expression outside loop", .{}); + return mod.failNode(parent_scope, node, "continue expression outside loop", .{}); }, } } diff --git a/test/stage2/test.zig b/test/stage2/test.zig index 242a01b599..8131a37c04 100644 --- a/test/stage2/test.zig +++ b/test/stage2/test.zig @@ -1128,97 +1128,97 @@ pub fn addCases(ctx: *TestContext) !void { , &[_][]const u8{":4:8: error: unable to infer variable type"}); } - //{ - // var case = ctx.exe("break/continue", linux_x64); + { + var case = ctx.exe("break/continue", linux_x64); - // // Break out of loop - // case.addCompareOutput( - // \\export fn _start() noreturn { - // \\ while (true) { - // \\ break; - // \\ } - // \\ - // \\ exit(); - // \\} - // \\ - // \\fn exit() noreturn { - // \\ asm volatile ("syscall" - // \\ : - // \\ : [number] "{rax}" (231), - // \\ [arg1] "{rdi}" (0) - // \\ : "rcx", "r11", "memory" - // \\ ); - // \\ unreachable; - // \\} - // , - // "", - // ); - // case.addCompareOutput( - // \\export fn _start() noreturn { - // \\ foo: while (true) { - // \\ break :foo; - // \\ } - // \\ - // \\ exit(); - // \\} - // \\ - // \\fn exit() noreturn { - // \\ asm volatile ("syscall" - // \\ : - // \\ : [number] "{rax}" (231), - // \\ [arg1] "{rdi}" (0) - // \\ : "rcx", "r11", "memory" - // \\ ); - // \\ unreachable; - // \\} - // , - // "", - // ); + // Break out of loop + case.addCompareOutput( + \\export fn _start() noreturn { + \\ while (true) { + \\ break; + \\ } + \\ + \\ exit(); + \\} + \\ + \\fn exit() noreturn { + \\ asm volatile ("syscall" + \\ : + \\ : [number] "{rax}" (231), + \\ [arg1] "{rdi}" (0) + \\ : "rcx", "r11", "memory" + \\ ); + \\ unreachable; + \\} + , + "", + ); + case.addCompareOutput( + \\export fn _start() noreturn { + \\ foo: while (true) { + \\ break :foo; + \\ } + \\ + \\ exit(); + \\} + \\ + \\fn exit() noreturn { + \\ asm volatile ("syscall" + \\ : + \\ : [number] "{rax}" (231), + \\ [arg1] "{rdi}" (0) + \\ : "rcx", "r11", "memory" + \\ ); + \\ unreachable; + \\} + , + "", + ); - // // Continue in loop - // case.addCompareOutput( - // \\export fn _start() noreturn { - // \\ var i: u64 = 0; - // \\ while (true) : (i+=1) { - // \\ if (i == 4) exit(); - // \\ continue; - // \\ } - // \\} - // \\ - // \\fn exit() noreturn { - // \\ asm volatile ("syscall" - // \\ : - // \\ : [number] "{rax}" (231), - // \\ [arg1] "{rdi}" (0) - // \\ : "rcx", "r11", "memory" - // \\ ); - // \\ unreachable; - // \\} - // , - // "", - // ); - // case.addCompareOutput( - // \\export fn _start() noreturn { - // \\ var i: u64 = 0; - // \\ foo: while (true) : (i+=1) { - // \\ if (i == 4) exit(); - // \\ continue :foo; - // \\ } - // \\} - // \\ - // \\fn exit() noreturn { - // \\ asm volatile ("syscall" - // \\ : - // \\ : [number] "{rax}" (231), - // \\ [arg1] "{rdi}" (0) - // \\ : "rcx", "r11", "memory" - // \\ ); - // \\ unreachable; - // \\} - // , - // "", - // ); - //} + // Continue in loop + case.addCompareOutput( + \\export fn _start() noreturn { + \\ var i: u64 = 0; + \\ while (true) : (i+=1) { + \\ if (i == 4) exit(); + \\ continue; + \\ } + \\} + \\ + \\fn exit() noreturn { + \\ asm volatile ("syscall" + \\ : + \\ : [number] "{rax}" (231), + \\ [arg1] "{rdi}" (0) + \\ : "rcx", "r11", "memory" + \\ ); + \\ unreachable; + \\} + , + "", + ); + case.addCompareOutput( + \\export fn _start() noreturn { + \\ var i: u64 = 0; + \\ foo: while (true) : (i+=1) { + \\ if (i == 4) exit(); + \\ continue :foo; + \\ } + \\} + \\ + \\fn exit() noreturn { + \\ asm volatile ("syscall" + \\ : + \\ : [number] "{rax}" (231), + \\ [arg1] "{rdi}" (0) + \\ : "rcx", "r11", "memory" + \\ ); + \\ unreachable; + \\} + , + "", + ); + } { var case = ctx.exe("unused labels", linux_x64);