aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorIsaac Freund <ifreund@ifreund.xyz>2021-03-26 11:46:42 +0100
committerIsaac Freund <ifreund@ifreund.xyz>2021-03-26 11:46:42 +0100
commit5eea13f5cc6ffc3c582faa59214010718b1390a4 (patch)
treeec71b8f00ff34492faa1617c6f82cee5a54c782a /src
parentb2deaf80279aab1322036e55a9646ecbaaa47f44 (diff)
downloadzig-5eea13f5cc6ffc3c582faa59214010718b1390a4.tar.gz
zig-5eea13f5cc6ffc3c582faa59214010718b1390a4.zip
astgen: implement slicing
Diffstat (limited to 'src')
-rw-r--r--src/astgen.zig86
1 files changed, 35 insertions, 51 deletions
diff --git a/src/astgen.zig b/src/astgen.zig
index 58d97bf9c2..05af58e720 100644
--- a/src/astgen.zig
+++ b/src/astgen.zig
@@ -435,11 +435,41 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) In
.for_simple => return forExpr(mod, scope, rl, node, tree.forSimple(node)),
.@"for" => return forExpr(mod, scope, rl, node, tree.forFull(node)),
- // TODO handling these separately would actually be simpler & have fewer branches
- // once we have a ZIR instruction for each of these 3 cases.
- .slice_open => return sliceExpr(mod, scope, rl, tree.sliceOpen(node)),
- .slice => return sliceExpr(mod, scope, rl, tree.slice(node)),
- .slice_sentinel => return sliceExpr(mod, scope, rl, tree.sliceSentinel(node)),
+ .slice_open => {
+ const lhs = try expr(mod, scope, .{ .ty = .usize_type }, node_datas[node].lhs);
+ const start = try expr(mod, scope, .{ .ty = .usize_type }, node_datas[node].rhs);
+ const result = try gz.addPlNode(.slice_start, node, zir.Inst.SliceStart{
+ .lhs = lhs,
+ .start = start,
+ });
+ return rvalue(mod, scope, rl, result, node);
+ },
+ .slice => {
+ const lhs = try expr(mod, scope, .{ .ty = .usize_type }, node_datas[node].lhs);
+ const extra = tree.extraData(node_datas[node].rhs, ast.Node.Slice);
+ const start = try expr(mod, scope, .{ .ty = .usize_type }, extra.start);
+ const end = try expr(mod, scope, .{ .ty = .usize_type }, extra.end);
+ const result = try gz.addPlNode(.slice_end, node, zir.Inst.SliceEnd{
+ .lhs = lhs,
+ .start = start,
+ .end = end,
+ });
+ return rvalue(mod, scope, rl, result, node);
+ },
+ .slice_sentinel => {
+ const lhs = try expr(mod, scope, .{ .ty = .usize_type }, node_datas[node].lhs);
+ const extra = tree.extraData(node_datas[node].rhs, ast.Node.SliceSentinel);
+ const start = try expr(mod, scope, .{ .ty = .usize_type }, extra.start);
+ const end = try expr(mod, scope, .{ .ty = .usize_type }, extra.end);
+ const sentinel = try expr(mod, scope, .{ .ty = .usize_type }, extra.sentinel);
+ const result = try gz.addPlNode(.slice_sentinel, node, zir.Inst.SliceSentinel{
+ .lhs = lhs,
+ .start = start,
+ .end = end,
+ .sentinel = sentinel,
+ });
+ return rvalue(mod, scope, rl, result, node);
+ },
.deref => {
const lhs = try expr(mod, scope, .none, node_datas[node].lhs);
@@ -1859,52 +1889,6 @@ fn arrayAccess(
}
}
-fn sliceExpr(
- mod: *Module,
- scope: *Scope,
- rl: ResultLoc,
- slice: ast.full.Slice,
-) InnerError!zir.Inst.Ref {
- if (true) @panic("TODO update for zir-memory-layout");
- const tree = scope.tree();
-
- const usize_type = try addZIRInstConst(mod, scope, src, .{
- .ty = Type.initTag(.type),
- .val = Value.initTag(.usize_type),
- });
-
- const array_ptr = try expr(mod, scope, .ref, slice.ast.sliced);
- const start = try expr(mod, scope, .{ .ty = usize_type }, slice.ast.start);
-
- if (slice.ast.sentinel == 0) {
- if (slice.ast.end == 0) {
- const result = try addZIRBinOp(mod, scope, src, .slice_start, array_ptr, start);
- return rvalue(mod, scope, rl, result);
- } else {
- const end = try expr(mod, scope, .{ .ty = usize_type }, slice.ast.end);
- // TODO a ZIR slice_open instruction
- const result = try addZIRInst(mod, scope, src, zir.Inst.Slice, .{
- .array_ptr = array_ptr,
- .start = start,
- }, .{ .end = end });
- return rvalue(mod, scope, rl, result);
- }
- }
-
- const end = try expr(mod, scope, .{ .ty = usize_type }, slice.ast.end);
- // TODO pass the proper result loc to this expression using a ZIR instruction
- // "get the child element type for a slice target".
- const sentinel = try expr(mod, scope, .none, slice.ast.sentinel);
- const result = try addZIRInst(mod, scope, src, zir.Inst.Slice, .{
- .array_ptr = array_ptr,
- .start = start,
- }, .{
- .end = end,
- .sentinel = sentinel,
- });
- return rvalue(mod, scope, rl, result);
-}
-
fn simpleBinOp(
mod: *Module,
scope: *Scope,