zig

fork of https://codeberg.org/ziglang/zig
Log | Files | Refs | README | LICENSE

commit cfc9f7422f3b0e4077eca42d7b71cd5523dad0a9 (tree)
parent 82101198f1ff2438f5db61d3a85eee3e0e1b95db
Author: Andrew Kelley <superjoe30@gmail.com>
Date:   Sun, 18 Dec 2016 20:22:28 -0500

IR: add MaybeOkOr instruction

Diffstat:
Msrc/ir.cpp | 44+++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 43 insertions(+), 1 deletion(-)

diff --git a/src/ir.cpp b/src/ir.cpp @@ -2194,6 +2194,48 @@ static IrInstruction *ir_gen_bool_and(IrBuilder *irb, Scope *scope, AstNode *nod return ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values); } +static IrInstruction *ir_gen_maybe_ok_or(IrBuilder *irb, Scope *parent_scope, AstNode *node) { + assert(node->type == NodeTypeBinOpExpr); + + AstNode *op1_node = node->data.bin_op_expr.op1; + AstNode *op2_node = node->data.bin_op_expr.op2; + + bool is_inline = ir_should_inline(irb); + + IrInstruction *maybe_ptr = ir_gen_node_extra(irb, op1_node, parent_scope, LValPurposeAddressOf); + if (maybe_ptr == irb->codegen->invalid_instruction) + return irb->codegen->invalid_instruction; + + IrInstruction *is_non_null = ir_build_test_null(irb, parent_scope, node, maybe_ptr); + + IrBasicBlock *ok_block = ir_build_basic_block(irb, parent_scope, "MaybeNonNull"); + IrBasicBlock *null_block = ir_build_basic_block(irb, parent_scope, "MaybeNull"); + IrBasicBlock *end_block = ir_build_basic_block(irb, parent_scope, "MaybeEnd"); + ir_build_cond_br(irb, parent_scope, node, is_non_null, ok_block, null_block, is_inline); + + ir_set_cursor_at_end(irb, null_block); + IrInstruction *null_result = ir_gen_node(irb, op2_node, parent_scope); + if (null_result == irb->codegen->invalid_instruction) + return irb->codegen->invalid_instruction; + IrBasicBlock *after_null_block = irb->current_basic_block; + ir_build_br(irb, parent_scope, node, end_block, is_inline); + + ir_set_cursor_at_end(irb, ok_block); + IrInstruction *unwrapped_ptr = ir_build_unwrap_maybe(irb, parent_scope, node, maybe_ptr, false); + IrInstruction *unwrapped_payload = ir_build_load_ptr(irb, parent_scope, node, unwrapped_ptr); + IrBasicBlock *after_ok_block = irb->current_basic_block; + ir_build_br(irb, parent_scope, node, end_block, is_inline); + + ir_set_cursor_at_end(irb, end_block); + IrInstruction **incoming_values = allocate<IrInstruction *>(2); + incoming_values[0] = null_result; + incoming_values[1] = unwrapped_payload; + IrBasicBlock **incoming_blocks = allocate<IrBasicBlock *>(2); + incoming_blocks[0] = after_null_block; + incoming_blocks[1] = after_ok_block; + return ir_build_phi(irb, parent_scope, node, 2, incoming_blocks, incoming_values); +} + static IrInstruction *ir_gen_bin_op(IrBuilder *irb, Scope *scope, AstNode *node) { assert(node->type == NodeTypeBinOpExpr); @@ -2284,7 +2326,7 @@ static IrInstruction *ir_gen_bin_op(IrBuilder *irb, Scope *scope, AstNode *node) case BinOpTypeArrayMult: return ir_gen_bin_op_id(irb, scope, node, IrBinOpArrayMult); case BinOpTypeUnwrapMaybe: - zig_panic("TODO gen IR for unwrap maybe binary operation"); + return ir_gen_maybe_ok_or(irb, scope, node); } zig_unreachable(); }