authorgravatar for timonkruiper@gmail.comTimon Kruiper <timonkruiper@gmail.com> 2021-03-23 23:55:52+01:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-03-24 15:48:18-07:00
log2c99fbb6728ee614740410662b1dcb33834cea2a
tree6663ca6d32e8198ecff3c6d5efd8a5f8fe77a608
parent0c6581e01d7ddd27f8ca30a71aec239aca8538e3

astgen: implement orelse


1 files changed, 53 insertions(+), 44 deletions(-)

src/astgen.zig+53-44
......@@ -553,6 +553,7 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) In
553553 mod,
554554 scope,
555555 rl,
556 node,
556557 node_datas[node].lhs,
557558 main_tokens[node],
558559 .is_null_ptr,
......@@ -565,6 +566,7 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) In
565566 mod,
566567 scope,
567568 rl,
569 node,
568570 node_datas[node].lhs,
569571 main_tokens[node],
570572 .is_null,
......@@ -1633,6 +1635,7 @@ fn orelseCatchExpr(
16331635 mod: *Module,
16341636 scope: *Scope,
16351637 rl: ResultLoc,
1638 node: ast.Node.Index,
16361639 lhs: ast.Node.Index,
16371640 op_token: ast.TokenIndex,
16381641 cond_op: zir.Inst.Tag,
......@@ -1641,16 +1644,11 @@ fn orelseCatchExpr(
16411644 rhs: ast.Node.Index,
16421645 payload_token: ?ast.TokenIndex,
16431646) InnerError!zir.Inst.Ref {
1644 if (true) @panic("TODO update for zir-memory-layout");
1645
1646 const gz = scope.getGenZir();
1647 const tree = gz.tree();
1648
1647 const parent_gz = scope.getGenZir();
16491648 var block_scope: Scope.GenZir = .{
16501649 .parent = scope,
1651 .decl = scope.ownerDecl().?,
1652 .arena = scope.arena(),
1653 .force_comptime = gz.force_comptime,
1650 .zir_code = parent_gz.zir_code,
1651 .force_comptime = parent_gz.force_comptime,
16541652 .instructions = .{},
16551653 };
16561654 setBlockResultLoc(&block_scope, rl);
......@@ -1661,62 +1659,73 @@ fn orelseCatchExpr(
16611659 // type, whereas this expression has the optional type. Later we make
16621660 // up for this fact by calling rvalue on the else branch.
16631661 block_scope.break_count += 1;
1664 const operand_rl = try makeOptionalTypeResultLoc(mod, &block_scope.base, src, block_scope.break_result_loc);
1662
1663 // TODO handle catch
1664 const operand_rl: ResultLoc = switch (block_scope.break_result_loc) {
1665 .ref => .ref,
1666 .discard, .none, .block_ptr, .inferred_ptr, .bitcasted_ptr => .none,
1667 .ty => |elem_ty| blk: {
1668 const wrapped_ty = try block_scope.addUnNode(.optional_type, elem_ty, node);
1669 break :blk .{ .ty = wrapped_ty };
1670 },
1671 .ptr => |ptr_ty| blk: {
1672 const wrapped_ty = try block_scope.addUnNode(.optional_type_from_ptr_elem, ptr_ty, node);
1673 break :blk .{ .ty = wrapped_ty };
1674 },
1675 };
16651676 const operand = try expr(mod, &block_scope.base, operand_rl, lhs);
1666 const cond = try addZIRUnOp(mod, &block_scope.base, src, cond_op, operand);
1677 const cond = try block_scope.addUnTok(cond_op, operand, op_token);
16671678
1668 const condbr = try addZIRInstSpecial(mod, &block_scope.base, src, zir.Inst.CondBr, .{
1669 .condition = cond,
1670 .then_body = undefined, // populated below
1671 .else_body = undefined, // populated below
1672 }, .{});
1679 const condbr = try block_scope.addCondBr(node);
16731680
1674 const block = try addZIRInstBlock(mod, scope, src, .block, .{
1675 .instructions = try block_scope.arena.dupe(zir.Inst.Ref, block_scope.instructions.items),
1676 });
1681 const block = try parent_gz.addBlock(.block, node);
1682 try parent_gz.instructions.append(mod.gpa, block);
1683 try block_scope.setBlockBody(block);
16771684
16781685 var then_scope: Scope.GenZir = .{
1679 .parent = &block_scope.base,
1680 .decl = block_scope.decl,
1681 .arena = block_scope.arena,
1686 .parent = scope,
1687 .zir_code = parent_gz.zir_code,
16821688 .force_comptime = block_scope.force_comptime,
16831689 .instructions = .{},
16841690 };
16851691 defer then_scope.instructions.deinit(mod.gpa);
16861692
1687 var err_val_scope: Scope.LocalVal = undefined;
1688 const then_sub_scope = blk: {
1689 const payload = payload_token orelse break :blk &then_scope.base;
1690 if (mem.eql(u8, tree.tokenSlice(payload), "_")) {
1691 return mod.failTok(&then_scope.base, payload, "discard of error capture; omit it instead", .{});
1692 }
1693 const err_name = try mod.identifierTokenString(scope, payload);
1694 err_val_scope = .{
1695 .parent = &then_scope.base,
1696 .gen_zir = &then_scope,
1697 .name = err_name,
1698 .inst = try addZIRUnOp(mod, &then_scope.base, src, unwrap_code_op, operand),
1699 };
1700 break :blk &err_val_scope.base;
1701 };
1693 if (payload_token != null) @panic("TODO handle catch");
1694 // var err_val_scope: Scope.LocalVal = undefined;
1695 // const then_sub_scope = blk: {
1696 // const payload = payload_token orelse break :blk &then_scope.base;
1697 // if (mem.eql(u8, tree.tokenSlice(payload), "_")) {
1698 // return mod.failTok(&then_scope.base, payload, "discard of error capture; omit it instead", .{});
1699 // }
1700 // const err_name = try mod.identifierTokenString(scope, payload);
1701 // err_val_scope = .{
1702 // .parent = &then_scope.base,
1703 // .gen_zir = &then_scope,
1704 // .name = err_name,
1705 // .inst = try addZIRUnOp(mod, &then_scope.base, src, unwrap_code_op, operand),
1706 // };
1707 // break :blk &err_val_scope.base;
1708 // };
17021709
17031710 block_scope.break_count += 1;
1704 const then_result = try expr(mod, then_sub_scope, block_scope.break_result_loc, rhs);
1711 const then_result = try expr(mod, &then_scope.base, block_scope.break_result_loc, rhs);
1712 // We hold off on the break instructions as well as copying the then/else
1713 // instructions into place until we know whether to keep store_to_block_ptr
1714 // instructions or not.
17051715
17061716 var else_scope: Scope.GenZir = .{
1707 .parent = &block_scope.base,
1708 .decl = block_scope.decl,
1709 .arena = block_scope.arena,
1717 .parent = scope,
1718 .zir_code = parent_gz.zir_code,
17101719 .force_comptime = block_scope.force_comptime,
17111720 .instructions = .{},
17121721 };
17131722 defer else_scope.instructions.deinit(mod.gpa);
17141723
17151724 // This could be a pointer or value depending on `unwrap_op`.
1716 const unwrapped_payload = try addZIRUnOp(mod, &else_scope.base, src, unwrap_op, operand);
1725 const unwrapped_payload = try else_scope.addUnNode(unwrap_op, operand, node);
17171726 const else_result = switch (rl) {
17181727 .ref => unwrapped_payload,
1719 else => try rvalue(mod, &else_scope.base, block_scope.break_result_loc, unwrapped_payload),
1728 else => try rvalue(mod, &else_scope.base, block_scope.break_result_loc, unwrapped_payload, node),
17201729 };
17211730
17221731 return finishThenElseBlock(
......@@ -1729,8 +1738,8 @@ fn orelseCatchExpr(
17291738 &else_scope,
17301739 condbr,
17311740 cond,
1732 src,
1733 src,
1741 node,
1742 node,
17341743 then_result,
17351744 else_result,
17361745 block,