diff options
| author | Timon Kruiper <timonkruiper@gmail.com> | 2021-03-23 23:55:52 +0100 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2021-03-24 15:48:18 -0700 |
| commit | 2c99fbb6728ee614740410662b1dcb33834cea2a (patch) | |
| tree | 6663ca6d32e8198ecff3c6d5efd8a5f8fe77a608 | |
| parent | 0c6581e01d7ddd27f8ca30a71aec239aca8538e3 (diff) | |
| download | zig-2c99fbb6728ee614740410662b1dcb33834cea2a.tar.gz zig-2c99fbb6728ee614740410662b1dcb33834cea2a.zip | |
astgen: implement orelse
| -rw-r--r-- | src/astgen.zig | 97 |
1 files changed, 53 insertions, 44 deletions
diff --git a/src/astgen.zig b/src/astgen.zig index 4ad7172773..c54d6b2d99 100644 --- a/src/astgen.zig +++ b/src/astgen.zig @@ -553,6 +553,7 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) In mod, scope, rl, + node, node_datas[node].lhs, main_tokens[node], .is_null_ptr, @@ -565,6 +566,7 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) In mod, scope, rl, + node, node_datas[node].lhs, main_tokens[node], .is_null, @@ -1633,6 +1635,7 @@ fn orelseCatchExpr( mod: *Module, scope: *Scope, rl: ResultLoc, + node: ast.Node.Index, lhs: ast.Node.Index, op_token: ast.TokenIndex, cond_op: zir.Inst.Tag, @@ -1641,16 +1644,11 @@ fn orelseCatchExpr( rhs: ast.Node.Index, payload_token: ?ast.TokenIndex, ) InnerError!zir.Inst.Ref { - if (true) @panic("TODO update for zir-memory-layout"); - - const gz = scope.getGenZir(); - const tree = gz.tree(); - + const parent_gz = scope.getGenZir(); var block_scope: Scope.GenZir = .{ .parent = scope, - .decl = scope.ownerDecl().?, - .arena = scope.arena(), - .force_comptime = gz.force_comptime, + .zir_code = parent_gz.zir_code, + .force_comptime = parent_gz.force_comptime, .instructions = .{}, }; setBlockResultLoc(&block_scope, rl); @@ -1661,62 +1659,73 @@ fn orelseCatchExpr( // type, whereas this expression has the optional type. Later we make // up for this fact by calling rvalue on the else branch. block_scope.break_count += 1; - const operand_rl = try makeOptionalTypeResultLoc(mod, &block_scope.base, src, block_scope.break_result_loc); + + // TODO handle catch + const operand_rl: ResultLoc = switch (block_scope.break_result_loc) { + .ref => .ref, + .discard, .none, .block_ptr, .inferred_ptr, .bitcasted_ptr => .none, + .ty => |elem_ty| blk: { + const wrapped_ty = try block_scope.addUnNode(.optional_type, elem_ty, node); + break :blk .{ .ty = wrapped_ty }; + }, + .ptr => |ptr_ty| blk: { + const wrapped_ty = try block_scope.addUnNode(.optional_type_from_ptr_elem, ptr_ty, node); + break :blk .{ .ty = wrapped_ty }; + }, + }; const operand = try expr(mod, &block_scope.base, operand_rl, lhs); - const cond = try addZIRUnOp(mod, &block_scope.base, src, cond_op, operand); + const cond = try block_scope.addUnTok(cond_op, operand, op_token); - const condbr = try addZIRInstSpecial(mod, &block_scope.base, src, zir.Inst.CondBr, .{ - .condition = cond, - .then_body = undefined, // populated below - .else_body = undefined, // populated below - }, .{}); + const condbr = try block_scope.addCondBr(node); - const block = try addZIRInstBlock(mod, scope, src, .block, .{ - .instructions = try block_scope.arena.dupe(zir.Inst.Ref, block_scope.instructions.items), - }); + const block = try parent_gz.addBlock(.block, node); + try parent_gz.instructions.append(mod.gpa, block); + try block_scope.setBlockBody(block); var then_scope: Scope.GenZir = .{ - .parent = &block_scope.base, - .decl = block_scope.decl, - .arena = block_scope.arena, + .parent = scope, + .zir_code = parent_gz.zir_code, .force_comptime = block_scope.force_comptime, .instructions = .{}, }; defer then_scope.instructions.deinit(mod.gpa); - var err_val_scope: Scope.LocalVal = undefined; - const then_sub_scope = blk: { - const payload = payload_token orelse break :blk &then_scope.base; - if (mem.eql(u8, tree.tokenSlice(payload), "_")) { - return mod.failTok(&then_scope.base, payload, "discard of error capture; omit it instead", .{}); - } - const err_name = try mod.identifierTokenString(scope, payload); - err_val_scope = .{ - .parent = &then_scope.base, - .gen_zir = &then_scope, - .name = err_name, - .inst = try addZIRUnOp(mod, &then_scope.base, src, unwrap_code_op, operand), - }; - break :blk &err_val_scope.base; - }; + if (payload_token != null) @panic("TODO handle catch"); + // var err_val_scope: Scope.LocalVal = undefined; + // const then_sub_scope = blk: { + // const payload = payload_token orelse break :blk &then_scope.base; + // if (mem.eql(u8, tree.tokenSlice(payload), "_")) { + // return mod.failTok(&then_scope.base, payload, "discard of error capture; omit it instead", .{}); + // } + // const err_name = try mod.identifierTokenString(scope, payload); + // err_val_scope = .{ + // .parent = &then_scope.base, + // .gen_zir = &then_scope, + // .name = err_name, + // .inst = try addZIRUnOp(mod, &then_scope.base, src, unwrap_code_op, operand), + // }; + // break :blk &err_val_scope.base; + // }; block_scope.break_count += 1; - const then_result = try expr(mod, then_sub_scope, block_scope.break_result_loc, rhs); + const then_result = try expr(mod, &then_scope.base, block_scope.break_result_loc, rhs); + // We hold off on the break instructions as well as copying the then/else + // instructions into place until we know whether to keep store_to_block_ptr + // instructions or not. var else_scope: Scope.GenZir = .{ - .parent = &block_scope.base, - .decl = block_scope.decl, - .arena = block_scope.arena, + .parent = scope, + .zir_code = parent_gz.zir_code, .force_comptime = block_scope.force_comptime, .instructions = .{}, }; defer else_scope.instructions.deinit(mod.gpa); // This could be a pointer or value depending on `unwrap_op`. - const unwrapped_payload = try addZIRUnOp(mod, &else_scope.base, src, unwrap_op, operand); + const unwrapped_payload = try else_scope.addUnNode(unwrap_op, operand, node); const else_result = switch (rl) { .ref => unwrapped_payload, - else => try rvalue(mod, &else_scope.base, block_scope.break_result_loc, unwrapped_payload), + else => try rvalue(mod, &else_scope.base, block_scope.break_result_loc, unwrapped_payload, node), }; return finishThenElseBlock( @@ -1729,8 +1738,8 @@ fn orelseCatchExpr( &else_scope, condbr, cond, - src, - src, + node, + node, then_result, else_result, block, |
