Commit a72bfd00cf

Andrew Kelley <andrew@ziglang.org>
2021-03-27 02:26:39
astgen: fix continue expressions
1 parent a217ad5
Changed files (2)
src
test
stage2
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", .{});
             },
         }
     }
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);