stage1 实现短路逻辑
This commit is contained in:
1 parent
b8e2bba140
commit
73c9a40abd
1 file changed
+39
-10
+39
-10
@@ -765,6 +765,7 @@ static spl_ir_node_ref_t emit_expr_raw(spl_ast2ir_t *a, spl_ast_node_ref_t ref)
|
||||
}
|
||||
case SPL_AST_EXPR_BINARY: {
|
||||
spl_binary_op_t op = n->binary.op;
|
||||
|
||||
if (op == SPL_OP_ASSIGN) {
|
||||
spl_ir_node_ref_t ptr = emit_lvalue(a, n->binary.left);
|
||||
spl_ir_node_ref_t v = emit_expr(a, n->binary.right);
|
||||
@@ -775,6 +776,7 @@ static spl_ir_node_ref_t emit_expr_raw(spl_ast2ir_t *a, spl_ast_node_ref_t ref)
|
||||
spl_ir_builder_mem_store(a->ir, t, ptr, v);
|
||||
return v;
|
||||
}
|
||||
|
||||
if (op >= SPL_OP_ASSIGN_ADD && op <= SPL_OP_ASSIGN_RSHIFT) {
|
||||
spl_ir_node_ref_t ptr = emit_lvalue(a, n->binary.left);
|
||||
if (!ptr)
|
||||
@@ -825,6 +827,43 @@ static spl_ir_node_ref_t emit_expr_raw(spl_ast2ir_t *a, spl_ast_node_ref_t ref)
|
||||
spl_ir_builder_mem_store(a->ir, t, ptr, res);
|
||||
return res;
|
||||
}
|
||||
|
||||
if (op == SPL_OP_BOOL_OR || op == SPL_OP_BOOL_AND) {
|
||||
spl_lang_type_id_t b_lang = spl_lang_make_bool(a->sema->type);
|
||||
spl_type_id_t b_ir = to_ir_type(a, b_lang);
|
||||
spl_ir_node_ref_t slot = spl_ir_builder_mem_alloca(a->ir, b_ir, const_usize(a, 1));
|
||||
|
||||
spl_ir_node_ref_t l = emit_expr(a, n->binary.left);
|
||||
if (!l)
|
||||
return 0;
|
||||
spl_ir_builder_mem_store(a->ir, b_ir, slot, l);
|
||||
|
||||
spl_ir_node_ref_t br = spl_ir_builder_control_br(a->ir, l);
|
||||
spl_ir_builder_block_end(a->ir);
|
||||
|
||||
usize rhs_blk = spl_ir_builder_block_begin(a->ir);
|
||||
spl_ir_node_ref_t r = emit_expr(a, n->binary.right);
|
||||
if (r)
|
||||
spl_ir_builder_mem_store(a->ir, b_ir, slot, r);
|
||||
/* 右侧可能以 ret / trap 终止,此时不能再补 jmp */
|
||||
spl_ir_node_ref_t rhs_end = 0;
|
||||
if (!a->ir->terminated)
|
||||
rhs_end = spl_ir_builder_control_jmp(a->ir);
|
||||
spl_ir_builder_block_end(a->ir);
|
||||
|
||||
usize end_blk = spl_ir_builder_block_begin(a->ir);
|
||||
/* control.br: cond != 0 -> true_label。AND 左侧真才进 rhs,
|
||||
OR 左侧假才进 rhs,所以 true/false 标签顺序相反。 */
|
||||
if (op == SPL_OP_BOOL_AND)
|
||||
spl_ir_builder_control_br_fixup(a->ir, br, rhs_blk, end_blk);
|
||||
else
|
||||
spl_ir_builder_control_br_fixup(a->ir, br, end_blk, rhs_blk);
|
||||
if (rhs_end)
|
||||
spl_ir_builder_control_jmp_fixup(a->ir, rhs_end, end_blk);
|
||||
|
||||
return spl_ir_builder_mem_load(a->ir, b_ir, slot);
|
||||
}
|
||||
|
||||
spl_ir_node_ref_t l = emit_expr(a, n->binary.left);
|
||||
spl_ir_node_ref_t r = emit_expr(a, n->binary.right);
|
||||
if (!l || !r)
|
||||
@@ -893,16 +932,6 @@ static spl_ir_node_ref_t emit_expr_raw(spl_ast2ir_t *a, spl_ast_node_ref_t ref)
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
case SPL_OP_BOOL_OR: {
|
||||
spl_ast_node_t *bmln = spl_ast_node(a->ast, n->binary.left);
|
||||
spl_type_id_t op_tid = bmln ? node_ir(a, bmln) : 0;
|
||||
return spl_ir_builder_arith_or(a->ir, op_tid, l, r);
|
||||
}
|
||||
case SPL_OP_BOOL_AND: {
|
||||
spl_ast_node_t *bmln = spl_ast_node(a->ast, n->binary.left);
|
||||
spl_type_id_t op_tid = bmln ? node_ir(a, bmln) : 0;
|
||||
return spl_ir_builder_arith_and(a->ir, op_tid, l, r);
|
||||
}
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user