authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-04-19 12:02:11-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-04-19 12:02:11-07:00
log3dadccec45832f31810d01b5599f984db5935e8c
tree4c7ceff9a437642c2e5392f26e7eb78799299c2c
parent3f60481be45fbde9e37d4b8aaff8a02e1db3e07d

AstGen: implement while optional and while error union


1 files changed, 89 insertions(+), 8 deletions(-)

src/AstGen.zig+89-8
......@@ -3414,6 +3414,8 @@ fn whileExpr(
34143414 while_full: ast.full.While,
34153415) InnerError!Zir.Inst.Ref {
34163416 const astgen = parent_gz.astgen;
3417 const tree = &astgen.file.tree;
3418 const token_tags = tree.tokens.items(.tag);
34173419
34183420 if (while_full.label_token) |label_token| {
34193421 try astgen.checkLabelRedefinition(scope, label_token);
......@@ -3443,14 +3445,37 @@ fn whileExpr(
34433445 };
34443446 defer continue_scope.instructions.deinit(astgen.gpa);
34453447
3446 const cond = c: {
3447 // TODO https://github.com/ziglang/zig/issues/7929
3448 const payload_is_ref = if (while_full.payload_token) |payload_token|
3449 token_tags[payload_token] == .asterisk
3450 else
3451 false;
3452
3453 const cond: struct {
3454 inst: Zir.Inst.Ref,
3455 bool_bit: Zir.Inst.Ref,
3456 } = c: {
34483457 if (while_full.error_token) |error_token| {
3449 return astgen.failTok(error_token, "TODO implement while error union", .{});
3458 const cond_rl: ResultLoc = if (payload_is_ref) .ref else .none;
3459 const err_union = try expr(&continue_scope, &continue_scope.base, cond_rl, while_full.ast.cond_expr);
3460 const tag: Zir.Inst.Tag = if (payload_is_ref) .is_err_ptr else .is_err;
3461 break :c .{
3462 .inst = err_union,
3463 .bool_bit = try continue_scope.addUnNode(tag, err_union, node),
3464 };
34503465 } else if (while_full.payload_token) |payload_token| {
3451 return astgen.failTok(payload_token, "TODO implement while optional", .{});
3466 const cond_rl: ResultLoc = if (payload_is_ref) .ref else .none;
3467 const optional = try expr(&continue_scope, &continue_scope.base, cond_rl, while_full.ast.cond_expr);
3468 const tag: Zir.Inst.Tag = if (payload_is_ref) .is_non_null_ptr else .is_non_null;
3469 break :c .{
3470 .inst = optional,
3471 .bool_bit = try continue_scope.addUnNode(tag, optional, node),
3472 };
34523473 } else {
3453 break :c try expr(&continue_scope, &continue_scope.base, bool_rl, while_full.ast.cond_expr);
3474 const cond = try expr(&continue_scope, &continue_scope.base, bool_rl, while_full.ast.cond_expr);
3475 break :c .{
3476 .inst = cond,
3477 .bool_bit = cond,
3478 };
34543479 }
34553480 };
34563481
......@@ -3489,7 +3514,44 @@ fn whileExpr(
34893514 };
34903515 defer then_scope.instructions.deinit(astgen.gpa);
34913516
3492 const then_sub_scope = &then_scope.base;
3517 var payload_val_scope: Scope.LocalVal = undefined;
3518
3519 const then_sub_scope = s: {
3520 if (while_full.error_token) |error_token| {
3521 const tag: Zir.Inst.Tag = if (payload_is_ref)
3522 .err_union_payload_unsafe_ptr
3523 else
3524 .err_union_payload_unsafe;
3525 const payload_inst = try then_scope.addUnNode(tag, cond.inst, node);
3526 const ident_name = try astgen.identifierTokenString(error_token);
3527 payload_val_scope = .{
3528 .parent = &then_scope.base,
3529 .gen_zir = &then_scope,
3530 .name = ident_name,
3531 .inst = payload_inst,
3532 .token_src = error_token,
3533 };
3534 break :s &payload_val_scope.base;
3535 } else if (while_full.payload_token) |payload_token| {
3536 const ident_token = if (payload_is_ref) payload_token + 1 else payload_token;
3537 const tag: Zir.Inst.Tag = if (payload_is_ref)
3538 .optional_payload_unsafe_ptr
3539 else
3540 .optional_payload_unsafe;
3541 const payload_inst = try then_scope.addUnNode(tag, cond.inst, node);
3542 const ident_name = try astgen.identifierTokenString(ident_token);
3543 payload_val_scope = .{
3544 .parent = &then_scope.base,
3545 .gen_zir = &then_scope,
3546 .name = ident_name,
3547 .inst = payload_inst,
3548 .token_src = ident_token,
3549 };
3550 break :s &payload_val_scope.base;
3551 } else {
3552 break :s &then_scope.base;
3553 }
3554 };
34933555
34943556 loop_scope.break_count += 1;
34953557 const then_result = try expr(&then_scope, then_sub_scope, loop_scope.break_result_loc, while_full.ast.then_expr);
......@@ -3509,7 +3571,26 @@ fn whileExpr(
35093571 result: Zir.Inst.Ref,
35103572 } = if (else_node != 0) blk: {
35113573 loop_scope.break_count += 1;
3512 const sub_scope = &else_scope.base;
3574 const sub_scope = s: {
3575 if (while_full.error_token) |error_token| {
3576 const tag: Zir.Inst.Tag = if (payload_is_ref)
3577 .err_union_code_ptr
3578 else
3579 .err_union_code;
3580 const payload_inst = try else_scope.addUnNode(tag, cond.inst, node);
3581 const ident_name = try astgen.identifierTokenString(error_token);
3582 payload_val_scope = .{
3583 .parent = &else_scope.base,
3584 .gen_zir = &else_scope,
3585 .name = ident_name,
3586 .inst = payload_inst,
3587 .token_src = error_token,
3588 };
3589 break :s &payload_val_scope.base;
3590 } else {
3591 break :s &else_scope.base;
3592 }
3593 };
35133594 break :blk .{
35143595 .src = else_node,
35153596 .result = try expr(&else_scope, sub_scope, loop_scope.break_result_loc, else_node),
......@@ -3534,7 +3615,7 @@ fn whileExpr(
35343615 &then_scope,
35353616 &else_scope,
35363617 condbr,
3537 cond,
3618 cond.bool_bit,
35383619 while_full.ast.then_expr,
35393620 else_info.src,
35403621 then_result,