authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-04-19 12:25:16-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-04-19 12:25:16-07:00
log27d4bea9a478e9c544329869d076b0e505d0e382
tree98ade88dbf91dcbaea5d06d4f175a081c140aeb5
parent3dadccec45832f31810d01b5599f984db5935e8c

AstGen: implement if optional, if error union


1 files changed, 90 insertions(+), 9 deletions(-)

src/AstGen.zig+90-9
...@@ -3264,6 +3264,9 @@ fn ifExpr(...@@ -3264,6 +3264,9 @@ fn ifExpr(
3264 if_full: ast.full.If,3264 if_full: ast.full.If,
3265) InnerError!Zir.Inst.Ref {3265) InnerError!Zir.Inst.Ref {
3266 const astgen = parent_gz.astgen;3266 const astgen = parent_gz.astgen;
3267 const tree = &astgen.file.tree;
3268 const token_tags = tree.tokens.items(.tag);
3269
3267 var block_scope: GenZir = .{3270 var block_scope: GenZir = .{
3268 .parent = scope,3271 .parent = scope,
3269 .decl_node_index = parent_gz.decl_node_index,3272 .decl_node_index = parent_gz.decl_node_index,
...@@ -3274,14 +3277,37 @@ fn ifExpr(...@@ -3274,14 +3277,37 @@ fn ifExpr(
3274 block_scope.setBreakResultLoc(rl);3277 block_scope.setBreakResultLoc(rl);
3275 defer block_scope.instructions.deinit(astgen.gpa);3278 defer block_scope.instructions.deinit(astgen.gpa);
32763279
3277 const cond = c: {3280 const payload_is_ref = if (if_full.payload_token) |payload_token|
3278 // TODO https://github.com/ziglang/zig/issues/79293281 token_tags[payload_token] == .asterisk
3282 else
3283 false;
3284
3285 const cond: struct {
3286 inst: Zir.Inst.Ref,
3287 bool_bit: Zir.Inst.Ref,
3288 } = c: {
3279 if (if_full.error_token) |error_token| {3289 if (if_full.error_token) |error_token| {
3280 return astgen.failTok(error_token, "TODO implement if error union", .{});3290 const cond_rl: ResultLoc = if (payload_is_ref) .ref else .none;
3291 const err_union = try expr(&block_scope, &block_scope.base, cond_rl, if_full.ast.cond_expr);
3292 const tag: Zir.Inst.Tag = if (payload_is_ref) .is_err_ptr else .is_err;
3293 break :c .{
3294 .inst = err_union,
3295 .bool_bit = try block_scope.addUnNode(tag, err_union, node),
3296 };
3281 } else if (if_full.payload_token) |payload_token| {3297 } else if (if_full.payload_token) |payload_token| {
3282 return astgen.failTok(payload_token, "TODO implement if optional", .{});3298 const cond_rl: ResultLoc = if (payload_is_ref) .ref else .none;
3299 const optional = try expr(&block_scope, &block_scope.base, cond_rl, if_full.ast.cond_expr);
3300 const tag: Zir.Inst.Tag = if (payload_is_ref) .is_non_null_ptr else .is_non_null;
3301 break :c .{
3302 .inst = optional,
3303 .bool_bit = try block_scope.addUnNode(tag, optional, node),
3304 };
3283 } else {3305 } else {
3284 break :c try expr(&block_scope, &block_scope.base, bool_rl, if_full.ast.cond_expr);3306 const cond = try expr(&block_scope, &block_scope.base, bool_rl, if_full.ast.cond_expr);
3307 break :c .{
3308 .inst = cond,
3309 .bool_bit = cond,
3310 };
3285 }3311 }
3286 };3312 };
32873313
...@@ -3300,8 +3326,44 @@ fn ifExpr(...@@ -3300,8 +3326,44 @@ fn ifExpr(
3300 };3326 };
3301 defer then_scope.instructions.deinit(astgen.gpa);3327 defer then_scope.instructions.deinit(astgen.gpa);
33023328
3303 // declare payload to the then_scope3329 var payload_val_scope: Scope.LocalVal = undefined;
3304 const then_sub_scope = &then_scope.base;3330
3331 const then_sub_scope = s: {
3332 if (if_full.error_token) |error_token| {
3333 const tag: Zir.Inst.Tag = if (payload_is_ref)
3334 .err_union_payload_unsafe_ptr
3335 else
3336 .err_union_payload_unsafe;
3337 const payload_inst = try then_scope.addUnNode(tag, cond.inst, node);
3338 const ident_name = try astgen.identifierTokenString(error_token);
3339 payload_val_scope = .{
3340 .parent = &then_scope.base,
3341 .gen_zir = &then_scope,
3342 .name = ident_name,
3343 .inst = payload_inst,
3344 .token_src = error_token,
3345 };
3346 break :s &payload_val_scope.base;
3347 } else if (if_full.payload_token) |payload_token| {
3348 const ident_token = if (payload_is_ref) payload_token + 1 else payload_token;
3349 const tag: Zir.Inst.Tag = if (payload_is_ref)
3350 .optional_payload_unsafe_ptr
3351 else
3352 .optional_payload_unsafe;
3353 const payload_inst = try then_scope.addUnNode(tag, cond.inst, node);
3354 const ident_name = try astgen.identifierTokenString(ident_token);
3355 payload_val_scope = .{
3356 .parent = &then_scope.base,
3357 .gen_zir = &then_scope,
3358 .name = ident_name,
3359 .inst = payload_inst,
3360 .token_src = ident_token,
3361 };
3362 break :s &payload_val_scope.base;
3363 } else {
3364 break :s &then_scope.base;
3365 }
3366 };
33053367
3306 block_scope.break_count += 1;3368 block_scope.break_count += 1;
3307 const then_result = try expr(&then_scope, then_sub_scope, block_scope.break_result_loc, if_full.ast.then_expr);3369 const then_result = try expr(&then_scope, then_sub_scope, block_scope.break_result_loc, if_full.ast.then_expr);
...@@ -3324,7 +3386,26 @@ fn ifExpr(...@@ -3324,7 +3386,26 @@ fn ifExpr(
3324 result: Zir.Inst.Ref,3386 result: Zir.Inst.Ref,
3325 } = if (else_node != 0) blk: {3387 } = if (else_node != 0) blk: {
3326 block_scope.break_count += 1;3388 block_scope.break_count += 1;
3327 const sub_scope = &else_scope.base;3389 const sub_scope = s: {
3390 if (if_full.error_token) |error_token| {
3391 const tag: Zir.Inst.Tag = if (payload_is_ref)
3392 .err_union_code_ptr
3393 else
3394 .err_union_code;
3395 const payload_inst = try else_scope.addUnNode(tag, cond.inst, node);
3396 const ident_name = try astgen.identifierTokenString(error_token);
3397 payload_val_scope = .{
3398 .parent = &else_scope.base,
3399 .gen_zir = &else_scope,
3400 .name = ident_name,
3401 .inst = payload_inst,
3402 .token_src = error_token,
3403 };
3404 break :s &payload_val_scope.base;
3405 } else {
3406 break :s &else_scope.base;
3407 }
3408 };
3328 break :blk .{3409 break :blk .{
3329 .src = else_node,3410 .src = else_node,
3330 .result = try expr(&else_scope, sub_scope, block_scope.break_result_loc, else_node),3411 .result = try expr(&else_scope, sub_scope, block_scope.break_result_loc, else_node),
...@@ -3343,7 +3424,7 @@ fn ifExpr(...@@ -3343,7 +3424,7 @@ fn ifExpr(
3343 &then_scope,3424 &then_scope,
3344 &else_scope,3425 &else_scope,
3345 condbr,3426 condbr,
3346 cond,3427 cond.bool_bit,
3347 if_full.ast.then_expr,3428 if_full.ast.then_expr,
3348 else_info.src,3429 else_info.src,
3349 then_result,3430 then_result,