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...@@ -553,6 +553,7 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) In
553 mod,553 mod,
554 scope,554 scope,
555 rl,555 rl,
556 node,
556 node_datas[node].lhs,557 node_datas[node].lhs,
557 main_tokens[node],558 main_tokens[node],
558 .is_null_ptr,559 .is_null_ptr,
...@@ -565,6 +566,7 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) In...@@ -565,6 +566,7 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) In
565 mod,566 mod,
566 scope,567 scope,
567 rl,568 rl,
569 node,
568 node_datas[node].lhs,570 node_datas[node].lhs,
569 main_tokens[node],571 main_tokens[node],
570 .is_null,572 .is_null,
...@@ -1633,6 +1635,7 @@ fn orelseCatchExpr(...@@ -1633,6 +1635,7 @@ fn orelseCatchExpr(
1633 mod: *Module,1635 mod: *Module,
1634 scope: *Scope,1636 scope: *Scope,
1635 rl: ResultLoc,1637 rl: ResultLoc,
1638 node: ast.Node.Index,
1636 lhs: ast.Node.Index,1639 lhs: ast.Node.Index,
1637 op_token: ast.TokenIndex,1640 op_token: ast.TokenIndex,
1638 cond_op: zir.Inst.Tag,1641 cond_op: zir.Inst.Tag,
...@@ -1641,16 +1644,11 @@ fn orelseCatchExpr(...@@ -1641,16 +1644,11 @@ fn orelseCatchExpr(
1641 rhs: ast.Node.Index,1644 rhs: ast.Node.Index,
1642 payload_token: ?ast.TokenIndex,1645 payload_token: ?ast.TokenIndex,
1643) InnerError!zir.Inst.Ref {1646) InnerError!zir.Inst.Ref {
1644 if (true) @panic("TODO update for zir-memory-layout");1647 const parent_gz = scope.getGenZir();
1645
1646 const gz = scope.getGenZir();
1647 const tree = gz.tree();
1648
1649 var block_scope: Scope.GenZir = .{1648 var block_scope: Scope.GenZir = .{
1650 .parent = scope,1649 .parent = scope,
1651 .decl = scope.ownerDecl().?,1650 .zir_code = parent_gz.zir_code,
1652 .arena = scope.arena(),1651 .force_comptime = parent_gz.force_comptime,
1653 .force_comptime = gz.force_comptime,
1654 .instructions = .{},1652 .instructions = .{},
1655 };1653 };
1656 setBlockResultLoc(&block_scope, rl);1654 setBlockResultLoc(&block_scope, rl);
...@@ -1661,62 +1659,73 @@ fn orelseCatchExpr(...@@ -1661,62 +1659,73 @@ fn orelseCatchExpr(
1661 // type, whereas this expression has the optional type. Later we make1659 // type, whereas this expression has the optional type. Later we make
1662 // up for this fact by calling rvalue on the else branch.1660 // up for this fact by calling rvalue on the else branch.
1663 block_scope.break_count += 1;1661 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 };
1665 const operand = try expr(mod, &block_scope.base, operand_rl, lhs);1676 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, .{1679 const condbr = try block_scope.addCondBr(node);
1669 .condition = cond,
1670 .then_body = undefined, // populated below
1671 .else_body = undefined, // populated below
1672 }, .{});
16731680
1674 const block = try addZIRInstBlock(mod, scope, src, .block, .{1681 const block = try parent_gz.addBlock(.block, node);
1675 .instructions = try block_scope.arena.dupe(zir.Inst.Ref, block_scope.instructions.items),1682 try parent_gz.instructions.append(mod.gpa, block);
1676 });1683 try block_scope.setBlockBody(block);
16771684
1678 var then_scope: Scope.GenZir = .{1685 var then_scope: Scope.GenZir = .{
1679 .parent = &block_scope.base,1686 .parent = scope,
1680 .decl = block_scope.decl,1687 .zir_code = parent_gz.zir_code,
1681 .arena = block_scope.arena,
1682 .force_comptime = block_scope.force_comptime,1688 .force_comptime = block_scope.force_comptime,
1683 .instructions = .{},1689 .instructions = .{},
1684 };1690 };
1685 defer then_scope.instructions.deinit(mod.gpa);1691 defer then_scope.instructions.deinit(mod.gpa);
16861692
1687 var err_val_scope: Scope.LocalVal = undefined;1693 if (payload_token != null) @panic("TODO handle catch");
1688 const then_sub_scope = blk: {1694 // var err_val_scope: Scope.LocalVal = undefined;
1689 const payload = payload_token orelse break :blk &then_scope.base;1695 // const then_sub_scope = blk: {
1690 if (mem.eql(u8, tree.tokenSlice(payload), "_")) {1696 // const payload = payload_token orelse break :blk &then_scope.base;
1691 return mod.failTok(&then_scope.base, payload, "discard of error capture; omit it instead", .{});1697 // if (mem.eql(u8, tree.tokenSlice(payload), "_")) {
1692 }1698 // return mod.failTok(&then_scope.base, payload, "discard of error capture; omit it instead", .{});
1693 const err_name = try mod.identifierTokenString(scope, payload);1699 // }
1694 err_val_scope = .{1700 // const err_name = try mod.identifierTokenString(scope, payload);
1695 .parent = &then_scope.base,1701 // err_val_scope = .{
1696 .gen_zir = &then_scope,1702 // .parent = &then_scope.base,
1697 .name = err_name,1703 // .gen_zir = &then_scope,
1698 .inst = try addZIRUnOp(mod, &then_scope.base, src, unwrap_code_op, operand),1704 // .name = err_name,
1699 };1705 // .inst = try addZIRUnOp(mod, &then_scope.base, src, unwrap_code_op, operand),
1700 break :blk &err_val_scope.base;1706 // };
1701 };1707 // break :blk &err_val_scope.base;
1708 // };
17021709
1703 block_scope.break_count += 1;1710 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
1706 var else_scope: Scope.GenZir = .{1716 var else_scope: Scope.GenZir = .{
1707 .parent = &block_scope.base,1717 .parent = scope,
1708 .decl = block_scope.decl,1718 .zir_code = parent_gz.zir_code,
1709 .arena = block_scope.arena,
1710 .force_comptime = block_scope.force_comptime,1719 .force_comptime = block_scope.force_comptime,
1711 .instructions = .{},1720 .instructions = .{},
1712 };1721 };
1713 defer else_scope.instructions.deinit(mod.gpa);1722 defer else_scope.instructions.deinit(mod.gpa);
17141723
1715 // This could be a pointer or value depending on `unwrap_op`.1724 // 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);
1717 const else_result = switch (rl) {1726 const else_result = switch (rl) {
1718 .ref => unwrapped_payload,1727 .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),
1720 };1729 };
17211730
1722 return finishThenElseBlock(1731 return finishThenElseBlock(
...@@ -1729,8 +1738,8 @@ fn orelseCatchExpr(...@@ -1729,8 +1738,8 @@ fn orelseCatchExpr(
1729 &else_scope,1738 &else_scope,
1730 condbr,1739 condbr,
1731 cond,1740 cond,
1732 src,1741 node,
1733 src,1742 node,
1734 then_result,1743 then_result,
1735 else_result,1744 else_result,
1736 block,1745 block,