| ... | ... | @@ -435,11 +435,41 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) In |
| 435 | 435 | .for_simple => return forExpr(mod, scope, rl, node, tree.forSimple(node)), |
| 436 | 436 | .@"for" => return forExpr(mod, scope, rl, node, tree.forFull(node)), |
| 437 | 437 | |
| 438 | | // TODO handling these separately would actually be simpler & have fewer branches |
| 439 | | // once we have a ZIR instruction for each of these 3 cases. |
| 440 | | .slice_open => return sliceExpr(mod, scope, rl, tree.sliceOpen(node)), |
| 441 | | .slice => return sliceExpr(mod, scope, rl, tree.slice(node)), |
| 442 | | .slice_sentinel => return sliceExpr(mod, scope, rl, tree.sliceSentinel(node)), |
| 438 | .slice_open => { |
| 439 | const lhs = try expr(mod, scope, .{ .ty = .usize_type }, node_datas[node].lhs); |
| 440 | const start = try expr(mod, scope, .{ .ty = .usize_type }, node_datas[node].rhs); |
| 441 | const result = try gz.addPlNode(.slice_start, node, zir.Inst.SliceStart{ |
| 442 | .lhs = lhs, |
| 443 | .start = start, |
| 444 | }); |
| 445 | return rvalue(mod, scope, rl, result, node); |
| 446 | }, |
| 447 | .slice => { |
| 448 | const lhs = try expr(mod, scope, .{ .ty = .usize_type }, node_datas[node].lhs); |
| 449 | const extra = tree.extraData(node_datas[node].rhs, ast.Node.Slice); |
| 450 | const start = try expr(mod, scope, .{ .ty = .usize_type }, extra.start); |
| 451 | const end = try expr(mod, scope, .{ .ty = .usize_type }, extra.end); |
| 452 | const result = try gz.addPlNode(.slice_end, node, zir.Inst.SliceEnd{ |
| 453 | .lhs = lhs, |
| 454 | .start = start, |
| 455 | .end = end, |
| 456 | }); |
| 457 | return rvalue(mod, scope, rl, result, node); |
| 458 | }, |
| 459 | .slice_sentinel => { |
| 460 | const lhs = try expr(mod, scope, .{ .ty = .usize_type }, node_datas[node].lhs); |
| 461 | const extra = tree.extraData(node_datas[node].rhs, ast.Node.SliceSentinel); |
| 462 | const start = try expr(mod, scope, .{ .ty = .usize_type }, extra.start); |
| 463 | const end = try expr(mod, scope, .{ .ty = .usize_type }, extra.end); |
| 464 | const sentinel = try expr(mod, scope, .{ .ty = .usize_type }, extra.sentinel); |
| 465 | const result = try gz.addPlNode(.slice_sentinel, node, zir.Inst.SliceSentinel{ |
| 466 | .lhs = lhs, |
| 467 | .start = start, |
| 468 | .end = end, |
| 469 | .sentinel = sentinel, |
| 470 | }); |
| 471 | return rvalue(mod, scope, rl, result, node); |
| 472 | }, |
| 443 | 473 | |
| 444 | 474 | .deref => { |
| 445 | 475 | const lhs = try expr(mod, scope, .none, node_datas[node].lhs); |
| ... | ... | @@ -1859,52 +1889,6 @@ fn arrayAccess( |
| 1859 | 1889 | } |
| 1860 | 1890 | } |
| 1861 | 1891 | |
| 1862 | | fn sliceExpr( |
| 1863 | | mod: *Module, |
| 1864 | | scope: *Scope, |
| 1865 | | rl: ResultLoc, |
| 1866 | | slice: ast.full.Slice, |
| 1867 | | ) InnerError!zir.Inst.Ref { |
| 1868 | | if (true) @panic("TODO update for zir-memory-layout"); |
| 1869 | | const tree = scope.tree(); |
| 1870 | | |
| 1871 | | const usize_type = try addZIRInstConst(mod, scope, src, .{ |
| 1872 | | .ty = Type.initTag(.type), |
| 1873 | | .val = Value.initTag(.usize_type), |
| 1874 | | }); |
| 1875 | | |
| 1876 | | const array_ptr = try expr(mod, scope, .ref, slice.ast.sliced); |
| 1877 | | const start = try expr(mod, scope, .{ .ty = usize_type }, slice.ast.start); |
| 1878 | | |
| 1879 | | if (slice.ast.sentinel == 0) { |
| 1880 | | if (slice.ast.end == 0) { |
| 1881 | | const result = try addZIRBinOp(mod, scope, src, .slice_start, array_ptr, start); |
| 1882 | | return rvalue(mod, scope, rl, result); |
| 1883 | | } else { |
| 1884 | | const end = try expr(mod, scope, .{ .ty = usize_type }, slice.ast.end); |
| 1885 | | // TODO a ZIR slice_open instruction |
| 1886 | | const result = try addZIRInst(mod, scope, src, zir.Inst.Slice, .{ |
| 1887 | | .array_ptr = array_ptr, |
| 1888 | | .start = start, |
| 1889 | | }, .{ .end = end }); |
| 1890 | | return rvalue(mod, scope, rl, result); |
| 1891 | | } |
| 1892 | | } |
| 1893 | | |
| 1894 | | const end = try expr(mod, scope, .{ .ty = usize_type }, slice.ast.end); |
| 1895 | | // TODO pass the proper result loc to this expression using a ZIR instruction |
| 1896 | | // "get the child element type for a slice target". |
| 1897 | | const sentinel = try expr(mod, scope, .none, slice.ast.sentinel); |
| 1898 | | const result = try addZIRInst(mod, scope, src, zir.Inst.Slice, .{ |
| 1899 | | .array_ptr = array_ptr, |
| 1900 | | .start = start, |
| 1901 | | }, .{ |
| 1902 | | .end = end, |
| 1903 | | .sentinel = sentinel, |
| 1904 | | }); |
| 1905 | | return rvalue(mod, scope, rl, result); |
| 1906 | | } |
| 1907 | | |
| 1908 | 1892 | fn simpleBinOp( |
| 1909 | 1893 | mod: *Module, |
| 1910 | 1894 | scope: *Scope, |