stage1 实现ir2vm 修复nob test命令的构建问题

This commit is contained in:
zzy committed 2026-09-12 18:51:10 +08:00
1 parent 87d9b7ea34
commit a64a96f9a4
11 files changed
+1565 -195

No files matched your search

+26 -49
View File
@@ -309,58 +309,31 @@ static spl_lang_type_id_t sema_check(spl_sema_t *sema, spl_ast_node_ref_t ref,
return bt;
}
/* 比较:数值类型允许异构比较;其他走 balance */
if (op == SPL_OP_CMP_EQ || op == SPL_OP_CMP_NE || op == SPL_OP_CMP_LT ||
op == SPL_OP_CMP_LE || op == SPL_OP_CMP_GT || op == SPL_OP_CMP_GE) {
/* 比较:结果 bool,节点存操作数类型;不依赖 expected */
spl_lang_type_id_t lt = sema_infer(sema, n->binary.left);
spl_lang_type_id_t rt = sema_infer(sema, n->binary.right);
if (!lt || !rt)
return 0;
spl_lang_type_node_t *ln = spl_lang_type_node(sema->type, lt);
spl_lang_type_node_t *rn = spl_lang_type_node(sema->type, rt);
bool l_num = ln && (ln->kind == SPL_LANG_TYPE_INT || ln->kind == SPL_LANG_TYPE_FLOAT);
bool r_num = rn && (rn->kind == SPL_LANG_TYPE_INT || rn->kind == SPL_LANG_TYPE_FLOAT);
if (l_num && r_num) {
/* 数值比较:允许异构。仅当一侧 comptime 时把另一侧具体类型下推 */
if (ln->kind == SPL_LANG_TYPE_INT && rn->kind == SPL_LANG_TYPE_INT) {
spl_type_node_t *lir = spl_type_node(sema->type, ln->ir_type_id);
spl_type_node_t *rir = spl_type_node(sema->type, rn->ir_type_id);
if (lir && lir->int_type.bits == 0)
sema_check(sema, n->binary.left, rt);
else if (rir && rir->int_type.bits == 0)
sema_check(sema, n->binary.right, lt);
} else if (ln->kind == SPL_LANG_TYPE_FLOAT && rn->kind == SPL_LANG_TYPE_FLOAT) {
spl_type_node_t *lir = spl_type_node(sema->type, ln->ir_type_id);
spl_type_node_t *rir = spl_type_node(sema->type, rn->ir_type_id);
if (lir && lir->float_type.bits == 0)
sema_check(sema, n->binary.left, rt);
else if (rir && rir->float_type.bits == 0)
sema_check(sema, n->binary.right, lt);
}
} else {
/* 非数值:要求 coerce 到共同类型 */
spl_lang_type_id_t common =
(lt == rt) ? lt : spl_lang_type_balance(sema->type, lt, rt);
if (!common) {
SPL_ERROR(&n->dbg, "comparison operands type mismatch");
sema->error_count++;
return 0;
}
if (!sema_check(sema, n->binary.left, common))
return 0;
if (!sema_check(sema, n->binary.right, common))
return 0;
spl_lang_type_id_t common = 0;
if (lt == rt)
common = lt;
else
common = spl_lang_type_balance(sema->type, lt, rt);
if (!common) {
SPL_ERROR(&n->dbg, "comparison operands type mismatch");
sema->error_count++;
return 0;
}
spl_lang_type_id_t bt = spl_lang_make_bool(sema->type);
n->resolved_lang_tid = bt;
n->expected_lang_tid = 0;
return bt;
}
sema_check(sema, n->binary.left, common);
sema_check(sema, n->binary.right, common);
n->resolved_lang_tid = common;
return spl_lang_make_bool(sema->type);
}
/* 算术 / 位 / 移位:两侧 check 到 expected */
if (!sema_check(sema, n->binary.left, expected))
return 0;
@@ -665,25 +638,29 @@ static spl_lang_type_id_t sema_infer(spl_sema_t *sema, spl_ast_node_ref_t ref) {
return bt;
}
/* 比较 */
if (op == SPL_OP_CMP_EQ || op == SPL_OP_CMP_NE || op == SPL_OP_CMP_LT ||
op == SPL_OP_CMP_LE || op == SPL_OP_CMP_GT || op == SPL_OP_CMP_GE) {
spl_lang_type_id_t lt = sema_infer(sema, n->binary.left);
spl_lang_type_id_t rt = sema_infer(sema, n->binary.right);
if (!lt || !rt)
return 0;
spl_lang_type_id_t common = 0;
if (lt == rt)
common = lt;
else
common = spl_lang_type_balance(sema->type, lt, rt);
if (common) {
sema_check(sema, n->binary.left, common);
sema_check(sema, n->binary.right, common);
if (!common) {
SPL_ERROR(&n->dbg, "comparison operands type mismatch");
sema->error_count++;
return 0;
}
spl_lang_type_id_t bt = spl_lang_make_bool(sema->type);
n->resolved_lang_tid = bt;
return bt;
sema_check(sema, n->binary.left, common);
sema_check(sema, n->binary.right, common);
n->resolved_lang_tid = common;
return spl_lang_make_bool(sema->type);
}
/* Range */