authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2020-08-28 14:35:13+03:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2020-09-03 15:05:43+03:00
logff7c6e1e3cea86e130e15a720c729a05763b5f08
treeab2343a0c5b94a7a8e28cdf963be40f8ea98b622
parent9a59cdcd41f5a05d70a02d89178afaf8789791c6
signaturelock-open Commit is signed but in an unrecognized format.

stage2: astgen orelse


1 files changed, 43 insertions(+), 25 deletions(-)

src-self-hosted/astgen.zig+43-25
...@@ -277,10 +277,10 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node) InnerEr...@@ -277,10 +277,10 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node) InnerEr
277 .ArrayAccess => return arrayAccess(mod, scope, rl, node.castTag(.ArrayAccess).?),277 .ArrayAccess => return arrayAccess(mod, scope, rl, node.castTag(.ArrayAccess).?),
278 .Catch => return catchExpr(mod, scope, rl, node.castTag(.Catch).?),278 .Catch => return catchExpr(mod, scope, rl, node.castTag(.Catch).?),
279 .Comptime => return comptimeKeyword(mod, scope, rl, node.castTag(.Comptime).?),279 .Comptime => return comptimeKeyword(mod, scope, rl, node.castTag(.Comptime).?),
280 .OrElse => return orelseExpr(mod, scope, rl, node.castTag(.OrElse).?),
280281
281 .Defer => return mod.failNode(scope, node, "TODO implement astgen.expr for .Defer", .{}),282 .Defer => return mod.failNode(scope, node, "TODO implement astgen.expr for .Defer", .{}),
282 .Range => return mod.failNode(scope, node, "TODO implement astgen.expr for .Range", .{}),283 .Range => return mod.failNode(scope, node, "TODO implement astgen.expr for .Range", .{}),
283 .OrElse => return mod.failNode(scope, node, "TODO implement astgen.expr for .OrElse", .{}),
284 .Await => return mod.failNode(scope, node, "TODO implement astgen.expr for .Await", .{}),284 .Await => return mod.failNode(scope, node, "TODO implement astgen.expr for .Await", .{}),
285 .Resume => return mod.failNode(scope, node, "TODO implement astgen.expr for .Resume", .{}),285 .Resume => return mod.failNode(scope, node, "TODO implement astgen.expr for .Resume", .{}),
286 .Try => return mod.failNode(scope, node, "TODO implement astgen.expr for .Try", .{}),286 .Try => return mod.failNode(scope, node, "TODO implement astgen.expr for .Try", .{}),
...@@ -790,13 +790,31 @@ fn errorType(mod: *Module, scope: *Scope, node: *ast.Node.OneToken) InnerError!*...@@ -790,13 +790,31 @@ fn errorType(mod: *Module, scope: *Scope, node: *ast.Node.OneToken) InnerError!*
790}790}
791791
792fn catchExpr(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.Catch) InnerError!*zir.Inst {792fn catchExpr(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.Catch) InnerError!*zir.Inst {
793 return orelseCatchExpr(mod, scope, rl, node.lhs, node.op_token, .iserr, .unwrap_err_unsafe, node.rhs, node.payload);
794}
795
796fn orelseExpr(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.SimpleInfixOp) InnerError!*zir.Inst {
797 return orelseCatchExpr(mod, scope, rl, node.lhs, node.op_token, .isnull, .unwrap_optional_unsafe, node.rhs, null);
798}
799
800fn orelseCatchExpr(
801 mod: *Module,
802 scope: *Scope,
803 rl: ResultLoc,
804 lhs: *ast.Node,
805 op_token: ast.TokenIndex,
806 cond_op: zir.Inst.Tag,
807 unwrap_op: zir.Inst.Tag,
808 rhs: *ast.Node,
809 payload_node: ?*ast.Node,
810) InnerError!*zir.Inst {
793 const tree = scope.tree();811 const tree = scope.tree();
794 const src = tree.token_locs[node.op_token].start;812 const src = tree.token_locs[op_token].start;
795813
796 const err_union_ptr = try expr(mod, scope, .ref, node.lhs);814 const operand_ptr = try expr(mod, scope, .ref, lhs);
797 // TODO we could avoid an unnecessary copy if .iserr took a pointer815 // TODO we could avoid an unnecessary copy if .iserr, .isnull took a pointer
798 const err_union = try addZIRUnOp(mod, scope, src, .deref, err_union_ptr);816 const err_union = try addZIRUnOp(mod, scope, src, .deref, operand_ptr);
799 const cond = try addZIRUnOp(mod, scope, src, .iserr, err_union);817 const cond = try addZIRUnOp(mod, scope, src, cond_op, err_union);
800818
801 var block_scope: Scope.GenZIR = .{819 var block_scope: Scope.GenZIR = .{
802 .parent = scope,820 .parent = scope,
...@@ -825,55 +843,55 @@ fn catchExpr(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.Catch)...@@ -825,55 +843,55 @@ fn catchExpr(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.Catch)
825 .inferred_ptr, .bitcasted_ptr, .block_ptr => .{ .block_ptr = block },843 .inferred_ptr, .bitcasted_ptr, .block_ptr => .{ .block_ptr = block },
826 };844 };
827845
828 var err_scope: Scope.GenZIR = .{846 var then_scope: Scope.GenZIR = .{
829 .parent = scope,847 .parent = scope,
830 .decl = block_scope.decl,848 .decl = block_scope.decl,
831 .arena = block_scope.arena,849 .arena = block_scope.arena,
832 .instructions = .{},850 .instructions = .{},
833 };851 };
834 defer err_scope.instructions.deinit(mod.gpa);852 defer then_scope.instructions.deinit(mod.gpa);
835853
836 var err_val_scope: Scope.LocalVal = undefined;854 var err_val_scope: Scope.LocalVal = undefined;
837 const err_sub_scope = blk: {855 const then_sub_scope = blk: {
838 const payload = node.payload orelse856 const payload = payload_node orelse
839 break :blk &err_scope.base;857 break :blk &then_scope.base;
840858
841 const err_name = tree.tokenSlice(payload.castTag(.Payload).?.error_symbol.firstToken());859 const err_name = tree.tokenSlice(payload.castTag(.Payload).?.error_symbol.firstToken());
842 if (mem.eql(u8, err_name, "_"))860 if (mem.eql(u8, err_name, "_"))
843 break :blk &err_scope.base;861 break :blk &then_scope.base;
844862
845 const unwrapped_err_ptr = try addZIRUnOp(mod, &err_scope.base, src, .unwrap_err_code, err_union_ptr);863 const unwrapped_err_ptr = try addZIRUnOp(mod, &then_scope.base, src, .unwrap_err_code, operand_ptr);
846 err_val_scope = .{864 err_val_scope = .{
847 .parent = &err_scope.base,865 .parent = &then_scope.base,
848 .gen_zir = &err_scope,866 .gen_zir = &then_scope,
849 .name = err_name,867 .name = err_name,
850 .inst = try addZIRUnOp(mod, &err_scope.base, src, .deref, unwrapped_err_ptr),868 .inst = try addZIRUnOp(mod, &then_scope.base, src, .deref, unwrapped_err_ptr),
851 };869 };
852 break :blk &err_val_scope.base;870 break :blk &err_val_scope.base;
853 };871 };
854872
855 _ = try addZIRInst(mod, &err_scope.base, src, zir.Inst.Break, .{873 _ = try addZIRInst(mod, &then_scope.base, src, zir.Inst.Break, .{
856 .block = block,874 .block = block,
857 .operand = try expr(mod, err_sub_scope, branch_rl, node.rhs),875 .operand = try expr(mod, then_sub_scope, branch_rl, rhs),
858 }, .{});876 }, .{});
859877
860 var not_err_scope: Scope.GenZIR = .{878 var else_scope: Scope.GenZIR = .{
861 .parent = scope,879 .parent = scope,
862 .decl = block_scope.decl,880 .decl = block_scope.decl,
863 .arena = block_scope.arena,881 .arena = block_scope.arena,
864 .instructions = .{},882 .instructions = .{},
865 };883 };
866 defer not_err_scope.instructions.deinit(mod.gpa);884 defer else_scope.instructions.deinit(mod.gpa);
867885
868 const unwrapped_payload = try addZIRUnOp(mod, &not_err_scope.base, src, .unwrap_err_unsafe, err_union_ptr);886 const unwrapped_payload = try addZIRUnOp(mod, &else_scope.base, src, unwrap_op, operand_ptr);
869 _ = try addZIRInst(mod, &not_err_scope.base, src, zir.Inst.Break, .{887 _ = try addZIRInst(mod, &else_scope.base, src, zir.Inst.Break, .{
870 .block = block,888 .block = block,
871 .operand = unwrapped_payload,889 .operand = unwrapped_payload,
872 }, .{});890 }, .{});
873891
874 condbr.positionals.then_body = .{ .instructions = try err_scope.arena.dupe(*zir.Inst, err_scope.instructions.items) };892 condbr.positionals.then_body = .{ .instructions = try then_scope.arena.dupe(*zir.Inst, then_scope.instructions.items) };
875 condbr.positionals.else_body = .{ .instructions = try not_err_scope.arena.dupe(*zir.Inst, not_err_scope.instructions.items) };893 condbr.positionals.else_body = .{ .instructions = try else_scope.arena.dupe(*zir.Inst, else_scope.instructions.items) };
876 return rlWrap(mod, scope, rl, &block.base);894 return rlWrapPtr(mod, scope, rl, &block.base);
877}895}
878896
879/// Return whether the identifier names of two tokens are equal. Resolves @"" tokens without allocating.897/// Return whether the identifier names of two tokens are equal. Resolves @"" tokens without allocating.