| ... | ... | @@ -370,8 +370,8 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) In |
| 370 | 370 | .array_cat => return simpleBinOp(mod, scope, rl, node, .array_cat), |
| 371 | 371 | .array_mult => return simpleBinOp(mod, scope, rl, node, .array_mul), |
| 372 | 372 | |
| 373 | | .bool_and => return boolBinOp(mod, scope, rl, node, true), |
| 374 | | .bool_or => return boolBinOp(mod, scope, rl, node, false), |
| 373 | .bool_and => return boolBinOp(mod, scope, rl, node, .bool_and), |
| 374 | .bool_or => return boolBinOp(mod, scope, rl, node, .bool_or), |
| 375 | 375 | |
| 376 | 376 | .bool_not => return boolNot(mod, scope, rl, node), |
| 377 | 377 | .bit_not => return bitNot(mod, scope, rl, node), |
| ... | ... | @@ -1805,87 +1805,71 @@ fn boolBinOp( |
| 1805 | 1805 | scope: *Scope, |
| 1806 | 1806 | rl: ResultLoc, |
| 1807 | 1807 | infix_node: ast.Node.Index, |
| 1808 | | is_bool_and: bool, |
| 1808 | kind: enum { bool_and, bool_or }, |
| 1809 | 1809 | ) InnerError!zir.Inst.Ref { |
| 1810 | | if (true) @panic("TODO update for zir-memory-layout"); |
| 1811 | 1810 | const tree = scope.tree(); |
| 1812 | 1811 | const node_datas = tree.nodes.items(.data); |
| 1813 | | const main_tokens = tree.nodes.items(.main_token); |
| 1812 | const bool_type = @enumToInt(zir.Const.bool_type); |
| 1813 | const gz = scope.getGenZir(); |
| 1814 | 1814 | |
| 1815 | | const bool_type = try addZIRInstConst(mod, scope, src, .{ |
| 1816 | | .ty = Type.initTag(.type), |
| 1817 | | .val = Value.initTag(.bool_type), |
| 1818 | | }); |
| 1815 | const lhs = try expr(mod, scope, .{ .ty = bool_type }, node_datas[infix_node].lhs); |
| 1819 | 1816 | |
| 1817 | const block_inst = try gz.addBlock(.block, infix_node); |
| 1818 | const block_ref = gz.zir_code.ref_start_index + block_inst; |
| 1820 | 1819 | var block_scope: Scope.GenZir = .{ |
| 1821 | 1820 | .parent = scope, |
| 1822 | | .decl = scope.ownerDecl().?, |
| 1823 | | .arena = scope.arena(), |
| 1824 | | .force_comptime = scope.isComptime(), |
| 1825 | | .instructions = .{}, |
| 1821 | .zir_code = gz.zir_code, |
| 1822 | .force_comptime = gz.force_comptime, |
| 1826 | 1823 | }; |
| 1827 | 1824 | defer block_scope.instructions.deinit(mod.gpa); |
| 1828 | 1825 | |
| 1829 | | const lhs = try expr(mod, scope, .{ .ty = bool_type }, node_datas[infix_node].lhs); |
| 1830 | | const condbr = try addZIRInstSpecial(mod, &block_scope.base, src, zir.Inst.CondBr, .{ |
| 1831 | | .condition = lhs, |
| 1832 | | .then_body = undefined, // populated below |
| 1833 | | .else_body = undefined, // populated below |
| 1834 | | }, .{}); |
| 1835 | | |
| 1836 | | const block = try addZIRInstBlock(mod, scope, src, .block, .{ |
| 1837 | | .instructions = try block_scope.arena.dupe(zir.Inst.Ref, block_scope.instructions.items), |
| 1838 | | }); |
| 1839 | | |
| 1840 | 1826 | var rhs_scope: Scope.GenZir = .{ |
| 1841 | | .parent = scope, |
| 1842 | | .decl = block_scope.decl, |
| 1843 | | .arena = block_scope.arena, |
| 1844 | | .force_comptime = block_scope.force_comptime, |
| 1845 | | .instructions = .{}, |
| 1827 | .parent = &block_scope.base, |
| 1828 | .zir_code = gz.zir_code, |
| 1829 | .force_comptime = gz.force_comptime, |
| 1846 | 1830 | }; |
| 1847 | 1831 | defer rhs_scope.instructions.deinit(mod.gpa); |
| 1848 | | |
| 1849 | 1832 | const rhs = try expr(mod, &rhs_scope.base, .{ .ty = bool_type }, node_datas[infix_node].rhs); |
| 1850 | | _ = try addZIRInst(mod, &rhs_scope.base, src, zir.Inst.Break, .{ |
| 1851 | | .block = block, |
| 1852 | | .operand = rhs, |
| 1853 | | }, .{}); |
| 1833 | _ = try rhs_scope.addBin(.@"break", block_inst, rhs); |
| 1854 | 1834 | |
| 1855 | | var const_scope: Scope.GenZir = .{ |
| 1856 | | .parent = scope, |
| 1857 | | .decl = block_scope.decl, |
| 1858 | | .arena = block_scope.arena, |
| 1859 | | .force_comptime = block_scope.force_comptime, |
| 1860 | | .instructions = .{}, |
| 1861 | | }; |
| 1862 | | defer const_scope.instructions.deinit(mod.gpa); |
| 1863 | | |
| 1864 | | _ = try addZIRInst(mod, &const_scope.base, src, zir.Inst.Break, .{ |
| 1865 | | .block = block, |
| 1866 | | .operand = try addZIRInstConst(mod, &const_scope.base, src, .{ |
| 1867 | | .ty = Type.initTag(.bool), |
| 1868 | | .val = if (is_bool_and) Value.initTag(.bool_false) else Value.initTag(.bool_true), |
| 1869 | | }), |
| 1870 | | }, .{}); |
| 1835 | // TODO: should we have zir.Const instructions for `break true` and `break false`? |
| 1836 | const new_index = @intCast(zir.Inst.Index, gz.zir_code.instructions.len); |
| 1837 | const break_true_false_ref = new_index + gz.zir_code.ref_start_index; |
| 1838 | try gz.zir_code.instructions.append(gz.zir_code.gpa, .{ .tag = .@"break", .data = .{ .bin = .{ |
| 1839 | .lhs = block_inst, |
| 1840 | .rhs = switch (kind) { |
| 1841 | .bool_and => @enumToInt(zir.Const.bool_false), |
| 1842 | .bool_or => @enumToInt(zir.Const.bool_true), |
| 1843 | }, |
| 1844 | } } }); |
| 1871 | 1845 | |
| 1872 | | if (is_bool_and) { |
| 1846 | switch (kind) { |
| 1873 | 1847 | // if lhs // AND |
| 1874 | 1848 | // break rhs |
| 1875 | 1849 | // else |
| 1876 | 1850 | // break false |
| 1877 | | condbr.positionals.then_body = .{ .instructions = try rhs_scope.arena.dupe(zir.Inst.Ref, rhs_scope.instructions.items) }; |
| 1878 | | condbr.positionals.else_body = .{ .instructions = try const_scope.arena.dupe(zir.Inst.Ref, const_scope.instructions.items) }; |
| 1879 | | } else { |
| 1851 | .bool_and => _ = try block_scope.addCondBr( |
| 1852 | lhs, |
| 1853 | rhs_scope.instructions.items, |
| 1854 | &[_]zir.Inst.Ref{break_true_false_ref}, |
| 1855 | infix_node, |
| 1856 | ), |
| 1880 | 1857 | // if lhs // OR |
| 1881 | 1858 | // break true |
| 1882 | 1859 | // else |
| 1883 | 1860 | // break rhs |
| 1884 | | condbr.positionals.then_body = .{ .instructions = try const_scope.arena.dupe(zir.Inst.Ref, const_scope.instructions.items) }; |
| 1885 | | condbr.positionals.else_body = .{ .instructions = try rhs_scope.arena.dupe(zir.Inst.Ref, rhs_scope.instructions.items) }; |
| 1861 | .bool_or => _ = try block_scope.addCondBr( |
| 1862 | lhs, |
| 1863 | &[_]zir.Inst.Ref{break_true_false_ref}, |
| 1864 | rhs_scope.instructions.items, |
| 1865 | infix_node, |
| 1866 | ), |
| 1886 | 1867 | } |
| 1887 | 1868 | |
| 1888 | | return rvalue(mod, scope, rl, &block.base); |
| 1869 | try gz.instructions.append(mod.gpa, block_inst); |
| 1870 | try copyBodyNoEliding(block_inst, block_scope); |
| 1871 | |
| 1872 | return rvalue(mod, scope, rl, block_ref, infix_node); |
| 1889 | 1873 | } |
| 1890 | 1874 | |
| 1891 | 1875 | fn ifExpr( |