mirror of
https://github.com/ziglang/zig.git
synced 2026-02-13 21:08:36 +00:00
AstGen: implement while optional and while error union
This commit is contained in:
parent
3f60481be4
commit
3dadccec45
@ -3414,6 +3414,8 @@ fn whileExpr(
|
||||
while_full: ast.full.While,
|
||||
) InnerError!Zir.Inst.Ref {
|
||||
const astgen = parent_gz.astgen;
|
||||
const tree = &astgen.file.tree;
|
||||
const token_tags = tree.tokens.items(.tag);
|
||||
|
||||
if (while_full.label_token) |label_token| {
|
||||
try astgen.checkLabelRedefinition(scope, label_token);
|
||||
@ -3443,14 +3445,37 @@ fn whileExpr(
|
||||
};
|
||||
defer continue_scope.instructions.deinit(astgen.gpa);
|
||||
|
||||
const cond = c: {
|
||||
// TODO https://github.com/ziglang/zig/issues/7929
|
||||
const payload_is_ref = if (while_full.payload_token) |payload_token|
|
||||
token_tags[payload_token] == .asterisk
|
||||
else
|
||||
false;
|
||||
|
||||
const cond: struct {
|
||||
inst: Zir.Inst.Ref,
|
||||
bool_bit: Zir.Inst.Ref,
|
||||
} = c: {
|
||||
if (while_full.error_token) |error_token| {
|
||||
return astgen.failTok(error_token, "TODO implement while error union", .{});
|
||||
const cond_rl: ResultLoc = if (payload_is_ref) .ref else .none;
|
||||
const err_union = try expr(&continue_scope, &continue_scope.base, cond_rl, while_full.ast.cond_expr);
|
||||
const tag: Zir.Inst.Tag = if (payload_is_ref) .is_err_ptr else .is_err;
|
||||
break :c .{
|
||||
.inst = err_union,
|
||||
.bool_bit = try continue_scope.addUnNode(tag, err_union, node),
|
||||
};
|
||||
} else if (while_full.payload_token) |payload_token| {
|
||||
return astgen.failTok(payload_token, "TODO implement while optional", .{});
|
||||
const cond_rl: ResultLoc = if (payload_is_ref) .ref else .none;
|
||||
const optional = try expr(&continue_scope, &continue_scope.base, cond_rl, while_full.ast.cond_expr);
|
||||
const tag: Zir.Inst.Tag = if (payload_is_ref) .is_non_null_ptr else .is_non_null;
|
||||
break :c .{
|
||||
.inst = optional,
|
||||
.bool_bit = try continue_scope.addUnNode(tag, optional, node),
|
||||
};
|
||||
} else {
|
||||
break :c try expr(&continue_scope, &continue_scope.base, bool_rl, while_full.ast.cond_expr);
|
||||
const cond = try expr(&continue_scope, &continue_scope.base, bool_rl, while_full.ast.cond_expr);
|
||||
break :c .{
|
||||
.inst = cond,
|
||||
.bool_bit = cond,
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
@ -3489,7 +3514,44 @@ fn whileExpr(
|
||||
};
|
||||
defer then_scope.instructions.deinit(astgen.gpa);
|
||||
|
||||
const then_sub_scope = &then_scope.base;
|
||||
var payload_val_scope: Scope.LocalVal = undefined;
|
||||
|
||||
const then_sub_scope = s: {
|
||||
if (while_full.error_token) |error_token| {
|
||||
const tag: Zir.Inst.Tag = if (payload_is_ref)
|
||||
.err_union_payload_unsafe_ptr
|
||||
else
|
||||
.err_union_payload_unsafe;
|
||||
const payload_inst = try then_scope.addUnNode(tag, cond.inst, node);
|
||||
const ident_name = try astgen.identifierTokenString(error_token);
|
||||
payload_val_scope = .{
|
||||
.parent = &then_scope.base,
|
||||
.gen_zir = &then_scope,
|
||||
.name = ident_name,
|
||||
.inst = payload_inst,
|
||||
.token_src = error_token,
|
||||
};
|
||||
break :s &payload_val_scope.base;
|
||||
} else if (while_full.payload_token) |payload_token| {
|
||||
const ident_token = if (payload_is_ref) payload_token + 1 else payload_token;
|
||||
const tag: Zir.Inst.Tag = if (payload_is_ref)
|
||||
.optional_payload_unsafe_ptr
|
||||
else
|
||||
.optional_payload_unsafe;
|
||||
const payload_inst = try then_scope.addUnNode(tag, cond.inst, node);
|
||||
const ident_name = try astgen.identifierTokenString(ident_token);
|
||||
payload_val_scope = .{
|
||||
.parent = &then_scope.base,
|
||||
.gen_zir = &then_scope,
|
||||
.name = ident_name,
|
||||
.inst = payload_inst,
|
||||
.token_src = ident_token,
|
||||
};
|
||||
break :s &payload_val_scope.base;
|
||||
} else {
|
||||
break :s &then_scope.base;
|
||||
}
|
||||
};
|
||||
|
||||
loop_scope.break_count += 1;
|
||||
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(
|
||||
result: Zir.Inst.Ref,
|
||||
} = if (else_node != 0) blk: {
|
||||
loop_scope.break_count += 1;
|
||||
const sub_scope = &else_scope.base;
|
||||
const sub_scope = s: {
|
||||
if (while_full.error_token) |error_token| {
|
||||
const tag: Zir.Inst.Tag = if (payload_is_ref)
|
||||
.err_union_code_ptr
|
||||
else
|
||||
.err_union_code;
|
||||
const payload_inst = try else_scope.addUnNode(tag, cond.inst, node);
|
||||
const ident_name = try astgen.identifierTokenString(error_token);
|
||||
payload_val_scope = .{
|
||||
.parent = &else_scope.base,
|
||||
.gen_zir = &else_scope,
|
||||
.name = ident_name,
|
||||
.inst = payload_inst,
|
||||
.token_src = error_token,
|
||||
};
|
||||
break :s &payload_val_scope.base;
|
||||
} else {
|
||||
break :s &else_scope.base;
|
||||
}
|
||||
};
|
||||
break :blk .{
|
||||
.src = else_node,
|
||||
.result = try expr(&else_scope, sub_scope, loop_scope.break_result_loc, else_node),
|
||||
@ -3534,7 +3615,7 @@ fn whileExpr(
|
||||
&then_scope,
|
||||
&else_scope,
|
||||
condbr,
|
||||
cond,
|
||||
cond.bool_bit,
|
||||
while_full.ast.then_expr,
|
||||
else_info.src,
|
||||
then_result,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user