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(...@@ -3414,6 +3414,8 @@ fn whileExpr(
3414 while_full: ast.full.While,3414 while_full: ast.full.While,
3415) InnerError!Zir.Inst.Ref {3415) InnerError!Zir.Inst.Ref {
3416 const astgen = parent_gz.astgen;3416 const astgen = parent_gz.astgen;
3417 const tree = &astgen.file.tree;
3418 const token_tags = tree.tokens.items(.tag);
34173419
3418 if (while_full.label_token) |label_token| {3420 if (while_full.label_token) |label_token| {
3419 try astgen.checkLabelRedefinition(scope, label_token);3421 try astgen.checkLabelRedefinition(scope, label_token);
...@@ -3443,14 +3445,37 @@ fn whileExpr(...@@ -3443,14 +3445,37 @@ fn whileExpr(
3443 };3445 };
3444 defer continue_scope.instructions.deinit(astgen.gpa);3446 defer continue_scope.instructions.deinit(astgen.gpa);
34453447
3446 const cond = c: {3448 const payload_is_ref = if (while_full.payload_token) |payload_token|
3447 // TODO https://github.com/ziglang/zig/issues/79293449 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: {
3448 if (while_full.error_token) |error_token| {3457 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 };
3450 } else if (while_full.payload_token) |payload_token| {3465 } 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 };
3452 } else {3473 } 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 };
3454 }3479 }
3455 };3480 };
34563481
...@@ -3489,7 +3514,44 @@ fn whileExpr(...@@ -3489,7 +3514,44 @@ fn whileExpr(
3489 };3514 };
3490 defer then_scope.instructions.deinit(astgen.gpa);3515 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
3494 loop_scope.break_count += 1;3556 loop_scope.break_count += 1;
3495 const then_result = try expr(&then_scope, then_sub_scope, loop_scope.break_result_loc, while_full.ast.then_expr);3557 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(...@@ -3509,7 +3571,26 @@ fn whileExpr(
3509 result: Zir.Inst.Ref,3571 result: Zir.Inst.Ref,
3510 } = if (else_node != 0) blk: {3572 } = if (else_node != 0) blk: {
3511 loop_scope.break_count += 1;3573 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 };
3513 break :blk .{3594 break :blk .{
3514 .src = else_node,3595 .src = else_node,
3515 .result = try expr(&else_scope, sub_scope, loop_scope.break_result_loc, else_node),3596 .result = try expr(&else_scope, sub_scope, loop_scope.break_result_loc, else_node),
...@@ -3534,7 +3615,7 @@ fn whileExpr(...@@ -3534,7 +3615,7 @@ fn whileExpr(
3534 &then_scope,3615 &then_scope,
3535 &else_scope,3616 &else_scope,
3536 condbr,3617 condbr,
3537 cond,3618 cond.bool_bit,
3538 while_full.ast.then_expr,3619 while_full.ast.then_expr,
3539 else_info.src,3620 else_info.src,
3540 then_result,3621 then_result,