| ... | ... | @@ -457,9 +457,9 @@ fn continueExpr(mod: *Module, parent_scope: *Scope, node: *ast.Node.ControlFlowE |
| 457 | 457 | continue; |
| 458 | 458 | } |
| 459 | 459 | |
| 460 | | return addZIRInst(mod, parent_scope, src, zir.Inst.BreakVoid, .{ |
| 460 | return addZirInstTag(mod, parent_scope, src, .break_void, .{ |
| 461 | 461 | .block = continue_block, |
| 462 | | }, .{}); |
| 462 | }); |
| 463 | 463 | }, |
| 464 | 464 | .local_val => scope = scope.cast(Scope.LocalVal).?.parent, |
| 465 | 465 | .local_ptr => scope = scope.cast(Scope.LocalPtr).?.parent, |
| ... | ... | @@ -1908,22 +1908,13 @@ fn whileExpr( |
| 1908 | 1908 | if (while_node.inline_token) |tok| |
| 1909 | 1909 | return mod.failTok(scope, tok, "TODO inline while", .{}); |
| 1910 | 1910 | |
| 1911 | | var expr_scope: Scope.GenZIR = .{ |
| 1911 | var loop_scope: Scope.GenZIR = .{ |
| 1912 | 1912 | .parent = scope, |
| 1913 | 1913 | .decl = scope.ownerDecl().?, |
| 1914 | 1914 | .arena = scope.arena(), |
| 1915 | 1915 | .instructions = .{}, |
| 1916 | 1916 | }; |
| 1917 | | setBlockResultLoc(&expr_scope, rl); |
| 1918 | | defer expr_scope.instructions.deinit(mod.gpa); |
| 1919 | | |
| 1920 | | var loop_scope: Scope.GenZIR = .{ |
| 1921 | | .parent = &expr_scope.base, |
| 1922 | | .decl = expr_scope.decl, |
| 1923 | | .arena = expr_scope.arena, |
| 1924 | | .instructions = .{}, |
| 1925 | | .break_result_loc = rl, |
| 1926 | | }; |
| 1917 | setBlockResultLoc(&loop_scope, rl); |
| 1927 | 1918 | defer loop_scope.instructions.deinit(mod.gpa); |
| 1928 | 1919 | |
| 1929 | 1920 | var continue_scope: Scope.GenZIR = .{ |
| ... | ... | @@ -1957,11 +1948,21 @@ fn whileExpr( |
| 1957 | 1948 | if (while_node.continue_expr) |cont_expr| { |
| 1958 | 1949 | _ = try expr(mod, &loop_scope.base, .{ .ty = void_type }, cont_expr); |
| 1959 | 1950 | } |
| 1960 | | const loop = try addZIRInstLoop(mod, &expr_scope.base, while_src, .{ |
| 1961 | | .instructions = try expr_scope.arena.dupe(*zir.Inst, loop_scope.instructions.items), |
| 1962 | | }); |
| 1951 | const loop = try scope.arena().create(zir.Inst.Loop); |
| 1952 | loop.* = .{ |
| 1953 | .base = .{ |
| 1954 | .tag = .loop, |
| 1955 | .src = while_src, |
| 1956 | }, |
| 1957 | .positionals = .{ |
| 1958 | .body = .{ |
| 1959 | .instructions = try scope.arena().dupe(*zir.Inst, loop_scope.instructions.items), |
| 1960 | }, |
| 1961 | }, |
| 1962 | .kw_args = .{}, |
| 1963 | }; |
| 1963 | 1964 | const while_block = try addZIRInstBlock(mod, scope, while_src, .block, .{ |
| 1964 | | .instructions = try expr_scope.arena.dupe(*zir.Inst, expr_scope.instructions.items), |
| 1965 | .instructions = try scope.arena().dupe(*zir.Inst, &[1]*zir.Inst{&loop.base}), |
| 1965 | 1966 | }); |
| 1966 | 1967 | loop_scope.break_block = while_block; |
| 1967 | 1968 | loop_scope.continue_block = cond_block; |
| ... | ... | @@ -1984,8 +1985,8 @@ fn whileExpr( |
| 1984 | 1985 | // declare payload to the then_scope |
| 1985 | 1986 | const then_sub_scope = try cond_kind.thenSubScope(mod, &then_scope, then_src, while_node.payload); |
| 1986 | 1987 | |
| 1987 | | expr_scope.break_count += 1; |
| 1988 | | const then_result = try expr(mod, then_sub_scope, expr_scope.break_result_loc, while_node.body); |
| 1988 | loop_scope.break_count += 1; |
| 1989 | const then_result = try expr(mod, then_sub_scope, loop_scope.break_result_loc, while_node.body); |
| 1989 | 1990 | |
| 1990 | 1991 | var else_scope: Scope.GenZIR = .{ |
| 1991 | 1992 | .parent = &continue_scope.base, |
| ... | ... | @@ -1996,17 +1997,15 @@ fn whileExpr( |
| 1996 | 1997 | defer else_scope.instructions.deinit(mod.gpa); |
| 1997 | 1998 | |
| 1998 | 1999 | var else_src: usize = undefined; |
| 1999 | | var else_sub_scope: *Module.Scope = undefined; |
| 2000 | 2000 | const else_result: ?*zir.Inst = if (while_node.@"else") |else_node| blk: { |
| 2001 | 2001 | else_src = tree.token_locs[else_node.body.lastToken()].start; |
| 2002 | 2002 | // declare payload to the then_scope |
| 2003 | | else_sub_scope = try cond_kind.elseSubScope(mod, &else_scope, else_src, else_node.payload); |
| 2003 | const else_sub_scope = try cond_kind.elseSubScope(mod, &else_scope, else_src, else_node.payload); |
| 2004 | 2004 | |
| 2005 | | expr_scope.break_count += 1; |
| 2006 | | break :blk try expr(mod, else_sub_scope, expr_scope.break_result_loc, else_node.body); |
| 2005 | loop_scope.break_count += 1; |
| 2006 | break :blk try expr(mod, else_sub_scope, loop_scope.break_result_loc, else_node.body); |
| 2007 | 2007 | } else blk: { |
| 2008 | 2008 | else_src = tree.token_locs[while_node.lastToken()].start; |
| 2009 | | else_sub_scope = &else_scope.base; |
| 2010 | 2009 | break :blk null; |
| 2011 | 2010 | }; |
| 2012 | 2011 | if (loop_scope.label) |some| { |
| ... | ... | @@ -2018,7 +2017,7 @@ fn whileExpr( |
| 2018 | 2017 | mod, |
| 2019 | 2018 | scope, |
| 2020 | 2019 | rl, |
| 2021 | | &expr_scope, |
| 2020 | &loop_scope, |
| 2022 | 2021 | &then_scope, |
| 2023 | 2022 | &else_scope, |
| 2024 | 2023 | &condbr.positionals.then_body, |
| ... | ... | @@ -2037,9 +2036,6 @@ fn forExpr( |
| 2037 | 2036 | rl: ResultLoc, |
| 2038 | 2037 | for_node: *ast.Node.For, |
| 2039 | 2038 | ) InnerError!*zir.Inst { |
| 2040 | | if (true) { |
| 2041 | | @panic("TODO reimplement this"); |
| 2042 | | } |
| 2043 | 2039 | if (for_node.label) |label| { |
| 2044 | 2040 | try checkLabelRedefinition(mod, scope, label); |
| 2045 | 2041 | } |
| ... | ... | @@ -2047,42 +2043,34 @@ fn forExpr( |
| 2047 | 2043 | if (for_node.inline_token) |tok| |
| 2048 | 2044 | return mod.failTok(scope, tok, "TODO inline for", .{}); |
| 2049 | 2045 | |
| 2050 | | var for_scope: Scope.GenZIR = .{ |
| 2051 | | .parent = scope, |
| 2052 | | .decl = scope.ownerDecl().?, |
| 2053 | | .arena = scope.arena(), |
| 2054 | | .instructions = .{}, |
| 2055 | | }; |
| 2056 | | defer for_scope.instructions.deinit(mod.gpa); |
| 2057 | | |
| 2058 | 2046 | // setup variables and constants |
| 2059 | 2047 | const tree = scope.tree(); |
| 2060 | 2048 | const for_src = tree.token_locs[for_node.for_token].start; |
| 2061 | 2049 | const index_ptr = blk: { |
| 2062 | | const usize_type = try addZIRInstConst(mod, &for_scope.base, for_src, .{ |
| 2050 | const usize_type = try addZIRInstConst(mod, scope, for_src, .{ |
| 2063 | 2051 | .ty = Type.initTag(.type), |
| 2064 | 2052 | .val = Value.initTag(.usize_type), |
| 2065 | 2053 | }); |
| 2066 | | const index_ptr = try addZIRUnOp(mod, &for_scope.base, for_src, .alloc, usize_type); |
| 2054 | const index_ptr = try addZIRUnOp(mod, scope, for_src, .alloc, usize_type); |
| 2067 | 2055 | // initialize to zero |
| 2068 | | const zero = try addZIRInstConst(mod, &for_scope.base, for_src, .{ |
| 2056 | const zero = try addZIRInstConst(mod, scope, for_src, .{ |
| 2069 | 2057 | .ty = Type.initTag(.usize), |
| 2070 | 2058 | .val = Value.initTag(.zero), |
| 2071 | 2059 | }); |
| 2072 | | _ = try addZIRBinOp(mod, &for_scope.base, for_src, .store, index_ptr, zero); |
| 2060 | _ = try addZIRBinOp(mod, scope, for_src, .store, index_ptr, zero); |
| 2073 | 2061 | break :blk index_ptr; |
| 2074 | 2062 | }; |
| 2075 | | const array_ptr = try expr(mod, &for_scope.base, .ref, for_node.array_expr); |
| 2063 | const array_ptr = try expr(mod, scope, .ref, for_node.array_expr); |
| 2076 | 2064 | const cond_src = tree.token_locs[for_node.array_expr.firstToken()].start; |
| 2077 | | const len = try addZIRUnOp(mod, &for_scope.base, cond_src, .indexable_ptr_len, array_ptr); |
| 2065 | const len = try addZIRUnOp(mod, scope, cond_src, .indexable_ptr_len, array_ptr); |
| 2078 | 2066 | |
| 2079 | 2067 | var loop_scope: Scope.GenZIR = .{ |
| 2080 | | .parent = &for_scope.base, |
| 2081 | | .decl = for_scope.decl, |
| 2082 | | .arena = for_scope.arena, |
| 2068 | .parent = scope, |
| 2069 | .decl = scope.ownerDecl().?, |
| 2070 | .arena = scope.arena(), |
| 2083 | 2071 | .instructions = .{}, |
| 2084 | | .break_result_loc = rl, |
| 2085 | 2072 | }; |
| 2073 | setBlockResultLoc(&loop_scope, rl); |
| 2086 | 2074 | defer loop_scope.instructions.deinit(mod.gpa); |
| 2087 | 2075 | |
| 2088 | 2076 | var cond_scope: Scope.GenZIR = .{ |
| ... | ... | @@ -2115,12 +2103,21 @@ fn forExpr( |
| 2115 | 2103 | const index_plus_one = try addZIRBinOp(mod, &loop_scope.base, for_src, .add, index_2, one); |
| 2116 | 2104 | _ = try addZIRBinOp(mod, &loop_scope.base, for_src, .store, index_ptr, index_plus_one); |
| 2117 | 2105 | |
| 2118 | | // looping stuff |
| 2119 | | const loop = try addZIRInstLoop(mod, &for_scope.base, for_src, .{ |
| 2120 | | .instructions = try for_scope.arena.dupe(*zir.Inst, loop_scope.instructions.items), |
| 2121 | | }); |
| 2106 | const loop = try scope.arena().create(zir.Inst.Loop); |
| 2107 | loop.* = .{ |
| 2108 | .base = .{ |
| 2109 | .tag = .loop, |
| 2110 | .src = for_src, |
| 2111 | }, |
| 2112 | .positionals = .{ |
| 2113 | .body = .{ |
| 2114 | .instructions = try scope.arena().dupe(*zir.Inst, loop_scope.instructions.items), |
| 2115 | }, |
| 2116 | }, |
| 2117 | .kw_args = .{}, |
| 2118 | }; |
| 2122 | 2119 | const for_block = try addZIRInstBlock(mod, scope, for_src, .block, .{ |
| 2123 | | .instructions = try for_scope.arena.dupe(*zir.Inst, for_scope.instructions.items), |
| 2120 | .instructions = try scope.arena().dupe(*zir.Inst, &[1]*zir.Inst{&loop.base}), |
| 2124 | 2121 | }); |
| 2125 | 2122 | loop_scope.break_block = for_block; |
| 2126 | 2123 | loop_scope.continue_block = cond_block; |
| ... | ... | @@ -2141,15 +2138,6 @@ fn forExpr( |
| 2141 | 2138 | }; |
| 2142 | 2139 | defer then_scope.instructions.deinit(mod.gpa); |
| 2143 | 2140 | |
| 2144 | | // Most result location types can be forwarded directly; however |
| 2145 | | // if we need to write to a pointer which has an inferred type, |
| 2146 | | // proper type inference requires peer type resolution on the while's |
| 2147 | | // branches. |
| 2148 | | const branch_rl: ResultLoc = switch (rl) { |
| 2149 | | .discard, .none, .ty, .ptr, .ref => rl, |
| 2150 | | .inferred_ptr, .bitcasted_ptr, .block_ptr => .{ .block_ptr = for_block }, |
| 2151 | | }; |
| 2152 | | |
| 2153 | 2141 | var index_scope: Scope.LocalPtr = undefined; |
| 2154 | 2142 | const then_sub_scope = blk: { |
| 2155 | 2143 | const payload = for_node.payload.castTag(.PointerIndexPayload).?; |
| ... | ... | @@ -2178,16 +2166,8 @@ fn forExpr( |
| 2178 | 2166 | break :blk &index_scope.base; |
| 2179 | 2167 | }; |
| 2180 | 2168 | |
| 2181 | | const then_result = try expr(mod, then_sub_scope, branch_rl, for_node.body); |
| 2182 | | if (!then_result.tag.isNoReturn()) { |
| 2183 | | _ = try addZIRInst(mod, then_sub_scope, then_src, zir.Inst.Break, .{ |
| 2184 | | .block = cond_block, |
| 2185 | | .operand = then_result, |
| 2186 | | }, .{}); |
| 2187 | | } |
| 2188 | | condbr.positionals.then_body = .{ |
| 2189 | | .instructions = try then_scope.arena.dupe(*zir.Inst, then_scope.instructions.items), |
| 2190 | | }; |
| 2169 | loop_scope.break_count += 1; |
| 2170 | const then_result = try expr(mod, then_sub_scope, loop_scope.break_result_loc, for_node.body); |
| 2191 | 2171 | |
| 2192 | 2172 | // else branch |
| 2193 | 2173 | var else_scope: Scope.GenZIR = .{ |
| ... | ... | @@ -2198,30 +2178,35 @@ fn forExpr( |
| 2198 | 2178 | }; |
| 2199 | 2179 | defer else_scope.instructions.deinit(mod.gpa); |
| 2200 | 2180 | |
| 2201 | | if (for_node.@"else") |else_node| { |
| 2202 | | const else_src = tree.token_locs[else_node.body.lastToken()].start; |
| 2203 | | const else_result = try expr(mod, &else_scope.base, branch_rl, else_node.body); |
| 2204 | | if (!else_result.tag.isNoReturn()) { |
| 2205 | | _ = try addZIRInst(mod, &else_scope.base, else_src, zir.Inst.Break, .{ |
| 2206 | | .block = for_block, |
| 2207 | | .operand = else_result, |
| 2208 | | }, .{}); |
| 2209 | | } |
| 2210 | | } else { |
| 2211 | | const else_src = tree.token_locs[for_node.lastToken()].start; |
| 2212 | | _ = try addZIRInst(mod, &else_scope.base, else_src, zir.Inst.BreakVoid, .{ |
| 2213 | | .block = for_block, |
| 2214 | | }, .{}); |
| 2215 | | } |
| 2216 | | condbr.positionals.else_body = .{ |
| 2217 | | .instructions = try else_scope.arena.dupe(*zir.Inst, else_scope.instructions.items), |
| 2181 | var else_src: usize = undefined; |
| 2182 | const else_result: ?*zir.Inst = if (for_node.@"else") |else_node| blk: { |
| 2183 | else_src = tree.token_locs[else_node.body.lastToken()].start; |
| 2184 | loop_scope.break_count += 1; |
| 2185 | break :blk try expr(mod, &else_scope.base, loop_scope.break_result_loc, else_node.body); |
| 2186 | } else blk: { |
| 2187 | else_src = tree.token_locs[for_node.lastToken()].start; |
| 2188 | break :blk null; |
| 2218 | 2189 | }; |
| 2219 | 2190 | if (loop_scope.label) |some| { |
| 2220 | 2191 | if (!some.used) { |
| 2221 | 2192 | return mod.fail(scope, tree.token_locs[some.token].start, "unused for label", .{}); |
| 2222 | 2193 | } |
| 2223 | 2194 | } |
| 2224 | | return &for_block.base; |
| 2195 | return finishThenElseBlock( |
| 2196 | mod, |
| 2197 | scope, |
| 2198 | rl, |
| 2199 | &loop_scope, |
| 2200 | &then_scope, |
| 2201 | &else_scope, |
| 2202 | &condbr.positionals.then_body, |
| 2203 | &condbr.positionals.else_body, |
| 2204 | then_src, |
| 2205 | else_src, |
| 2206 | then_result, |
| 2207 | else_result, |
| 2208 | for_block, |
| 2209 | ); |
| 2225 | 2210 | } |
| 2226 | 2211 | |
| 2227 | 2212 | fn getRangeNode(node: *ast.Node) ?*ast.Node.SimpleInfixOp { |