authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-03-26 18:26:39-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-03-26 18:26:39-07:00
loga72bfd00cf07da50a94a024d6f74167aa41382c5
tree8fe496f8fc343f58f8dc315dad4d5638ab303a8c
parenta217ad59c770eb3915f5b98f177a012181b7f48e

astgen: fix continue expressions


2 files changed, 97 insertions(+), 99 deletions(-)

src/astgen.zig+8-10
...@@ -766,11 +766,9 @@ fn breakExpr(mod: *Module, parent_scope: *Scope, node: ast.Node.Index) InnerErro...@@ -766,11 +766,9 @@ fn breakExpr(mod: *Module, parent_scope: *Scope, node: ast.Node.Index) InnerErro
766}766}
767767
768fn continueExpr(mod: *Module, parent_scope: *Scope, node: ast.Node.Index) InnerError!zir.Inst.Ref {768fn continueExpr(mod: *Module, parent_scope: *Scope, node: ast.Node.Index) InnerError!zir.Inst.Ref {
769 if (true) @panic("TODO update for zir-memory-layout");769 const parent_gz = parent_scope.getGenZir();
770 const tree = parent_scope.tree();770 const tree = parent_gz.tree();
771 const node_datas = tree.nodes.items(.data);771 const node_datas = tree.nodes.items(.data);
772 const main_tokens = tree.nodes.items(.main_token);
773
774 const break_label = node_datas[node].lhs;772 const break_label = node_datas[node].lhs;
775773
776 // Look for the label in the scope.774 // Look for the label in the scope.
...@@ -779,10 +777,11 @@ fn continueExpr(mod: *Module, parent_scope: *Scope, node: ast.Node.Index) InnerE...@@ -779,10 +777,11 @@ fn continueExpr(mod: *Module, parent_scope: *Scope, node: ast.Node.Index) InnerE
779 switch (scope.tag) {777 switch (scope.tag) {
780 .gen_zir => {778 .gen_zir => {
781 const gen_zir = scope.cast(Scope.GenZir).?;779 const gen_zir = scope.cast(Scope.GenZir).?;
782 const continue_block = gen_zir.continue_block orelse {780 const continue_block = gen_zir.continue_block;
781 if (continue_block == 0) {
783 scope = gen_zir.parent;782 scope = gen_zir.parent;
784 continue;783 continue;
785 };784 }
786 if (break_label != 0) blk: {785 if (break_label != 0) blk: {
787 if (gen_zir.label) |*label| {786 if (gen_zir.label) |*label| {
788 if (try tokenIdentEql(mod, parent_scope, label.token, break_label)) {787 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...@@ -795,9 +794,8 @@ fn continueExpr(mod: *Module, parent_scope: *Scope, node: ast.Node.Index) InnerE
795 continue;794 continue;
796 }795 }
797796
798 _ = try addZirInstTag(mod, parent_scope, src, .break_void, .{797 // TODO emit a break_inline if the loop being continued is inline
799 .block = continue_block,798 _ = try parent_gz.addBreak(.@"break", continue_block, .void_value);
800 });
801 return zir.Inst.Ref.unreachable_value;799 return zir.Inst.Ref.unreachable_value;
802 },800 },
803 .local_val => scope = scope.cast(Scope.LocalVal).?.parent,801 .local_val => scope = scope.cast(Scope.LocalVal).?.parent,
...@@ -806,7 +804,7 @@ fn continueExpr(mod: *Module, parent_scope: *Scope, node: ast.Node.Index) InnerE...@@ -806,7 +804,7 @@ fn continueExpr(mod: *Module, parent_scope: *Scope, node: ast.Node.Index) InnerE
806 const label_name = try mod.identifierTokenString(parent_scope, break_label);804 const label_name = try mod.identifierTokenString(parent_scope, break_label);
807 return mod.failTok(parent_scope, break_label, "label not found: '{s}'", .{label_name});805 return mod.failTok(parent_scope, break_label, "label not found: '{s}'", .{label_name});
808 } else {806 } else {
809 return mod.failTok(parent_scope, src, "continue expression outside loop", .{});807 return mod.failNode(parent_scope, node, "continue expression outside loop", .{});
810 },808 },
811 }809 }
812 }810 }
test/stage2/test.zig+89-89
...@@ -1128,97 +1128,97 @@ pub fn addCases(ctx: *TestContext) !void {...@@ -1128,97 +1128,97 @@ pub fn addCases(ctx: *TestContext) !void {
1128 , &[_][]const u8{":4:8: error: unable to infer variable type"});1128 , &[_][]const u8{":4:8: error: unable to infer variable type"});
1129 }1129 }
11301130
1131 //{1131 {
1132 // var case = ctx.exe("break/continue", linux_x64);1132 var case = ctx.exe("break/continue", linux_x64);
11331133
1134 // // Break out of loop1134 // Break out of loop
1135 // case.addCompareOutput(1135 case.addCompareOutput(
1136 // \\export fn _start() noreturn {1136 \\export fn _start() noreturn {
1137 // \\ while (true) {1137 \\ while (true) {
1138 // \\ break;1138 \\ break;
1139 // \\ }1139 \\ }
1140 // \\1140 \\
1141 // \\ exit();1141 \\ exit();
1142 // \\}1142 \\}
1143 // \\1143 \\
1144 // \\fn exit() noreturn {1144 \\fn exit() noreturn {
1145 // \\ asm volatile ("syscall"1145 \\ asm volatile ("syscall"
1146 // \\ :1146 \\ :
1147 // \\ : [number] "{rax}" (231),1147 \\ : [number] "{rax}" (231),
1148 // \\ [arg1] "{rdi}" (0)1148 \\ [arg1] "{rdi}" (0)
1149 // \\ : "rcx", "r11", "memory"1149 \\ : "rcx", "r11", "memory"
1150 // \\ );1150 \\ );
1151 // \\ unreachable;1151 \\ unreachable;
1152 // \\}1152 \\}
1153 // ,1153 ,
1154 // "",1154 "",
1155 // );1155 );
1156 // case.addCompareOutput(1156 case.addCompareOutput(
1157 // \\export fn _start() noreturn {1157 \\export fn _start() noreturn {
1158 // \\ foo: while (true) {1158 \\ foo: while (true) {
1159 // \\ break :foo;1159 \\ break :foo;
1160 // \\ }1160 \\ }
1161 // \\1161 \\
1162 // \\ exit();1162 \\ exit();
1163 // \\}1163 \\}
1164 // \\1164 \\
1165 // \\fn exit() noreturn {1165 \\fn exit() noreturn {
1166 // \\ asm volatile ("syscall"1166 \\ asm volatile ("syscall"
1167 // \\ :1167 \\ :
1168 // \\ : [number] "{rax}" (231),1168 \\ : [number] "{rax}" (231),
1169 // \\ [arg1] "{rdi}" (0)1169 \\ [arg1] "{rdi}" (0)
1170 // \\ : "rcx", "r11", "memory"1170 \\ : "rcx", "r11", "memory"
1171 // \\ );1171 \\ );
1172 // \\ unreachable;1172 \\ unreachable;
1173 // \\}1173 \\}
1174 // ,1174 ,
1175 // "",1175 "",
1176 // );1176 );
11771177
1178 // // Continue in loop1178 // Continue in loop
1179 // case.addCompareOutput(1179 case.addCompareOutput(
1180 // \\export fn _start() noreturn {1180 \\export fn _start() noreturn {
1181 // \\ var i: u64 = 0;1181 \\ var i: u64 = 0;
1182 // \\ while (true) : (i+=1) {1182 \\ while (true) : (i+=1) {
1183 // \\ if (i == 4) exit();1183 \\ if (i == 4) exit();
1184 // \\ continue;1184 \\ continue;
1185 // \\ }1185 \\ }
1186 // \\}1186 \\}
1187 // \\1187 \\
1188 // \\fn exit() noreturn {1188 \\fn exit() noreturn {
1189 // \\ asm volatile ("syscall"1189 \\ asm volatile ("syscall"
1190 // \\ :1190 \\ :
1191 // \\ : [number] "{rax}" (231),1191 \\ : [number] "{rax}" (231),
1192 // \\ [arg1] "{rdi}" (0)1192 \\ [arg1] "{rdi}" (0)
1193 // \\ : "rcx", "r11", "memory"1193 \\ : "rcx", "r11", "memory"
1194 // \\ );1194 \\ );
1195 // \\ unreachable;1195 \\ unreachable;
1196 // \\}1196 \\}
1197 // ,1197 ,
1198 // "",1198 "",
1199 // );1199 );
1200 // case.addCompareOutput(1200 case.addCompareOutput(
1201 // \\export fn _start() noreturn {1201 \\export fn _start() noreturn {
1202 // \\ var i: u64 = 0;1202 \\ var i: u64 = 0;
1203 // \\ foo: while (true) : (i+=1) {1203 \\ foo: while (true) : (i+=1) {
1204 // \\ if (i == 4) exit();1204 \\ if (i == 4) exit();
1205 // \\ continue :foo;1205 \\ continue :foo;
1206 // \\ }1206 \\ }
1207 // \\}1207 \\}
1208 // \\1208 \\
1209 // \\fn exit() noreturn {1209 \\fn exit() noreturn {
1210 // \\ asm volatile ("syscall"1210 \\ asm volatile ("syscall"
1211 // \\ :1211 \\ :
1212 // \\ : [number] "{rax}" (231),1212 \\ : [number] "{rax}" (231),
1213 // \\ [arg1] "{rdi}" (0)1213 \\ [arg1] "{rdi}" (0)
1214 // \\ : "rcx", "r11", "memory"1214 \\ : "rcx", "r11", "memory"
1215 // \\ );1215 \\ );
1216 // \\ unreachable;1216 \\ unreachable;
1217 // \\}1217 \\}
1218 // ,1218 ,
1219 // "",1219 "",
1220 // );1220 );
1221 //}1221 }
12221222
1223 {1223 {
1224 var case = ctx.exe("unused labels", linux_x64);1224 var case = ctx.exe("unused labels", linux_x64);