authorgravatar for mail@isaacfreund.comIsaac Freund <mail@isaacfreund.com> 2021-03-26 11:46:42+01:00
committergravatar for mail@isaacfreund.comIsaac Freund <mail@isaacfreund.com> 2021-03-26 11:46:42+01:00
log5eea13f5cc6ffc3c582faa59214010718b1390a4
treeec71b8f00ff34492faa1617c6f82cee5a54c782a
parentb2deaf80279aab1322036e55a9646ecbaaa47f44
signature Commit is signed but in an unrecognized format.

astgen: implement slicing


1 files changed, 35 insertions(+), 51 deletions(-)

src/astgen.zig+35-51
......@@ -435,11 +435,41 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) In
435435 .for_simple => return forExpr(mod, scope, rl, node, tree.forSimple(node)),
436436 .@"for" => return forExpr(mod, scope, rl, node, tree.forFull(node)),
437437
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 },
443473
444474 .deref => {
445475 const lhs = try expr(mod, scope, .none, node_datas[node].lhs);
......@@ -1859,52 +1889,6 @@ fn arrayAccess(
18591889 }
18601890}
18611891
1862fn 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
19081892fn simpleBinOp(
19091893 mod: *Module,
19101894 scope: *Scope,