stage2 更多底层函数 stage1 layout正确使用 内置函数重新编写

This commit is contained in:
zzy committed 2026-09-17 22:03:23 +08:00
1 parent fb0ff9b663
commit 4141e7d574
15 files changed
+2588 -122

No files matched your search

+55 -7
View File
@@ -938,9 +938,9 @@ static spl_lang_type_id_t sema_intrin_call(spl_sema_t *sema, spl_ast_node_t *n,
case SPL_INTRIN_TRUNCATE:
case SPL_INTRIN_BIT_CAST:
case SPL_INTRIN_FLOAT_CAST:
case SPL_INTRIN_INT_FROM_FLOAT:
case SPL_INTRIN_FLOAT_FROM_INT:
case SPL_INTRIN_PTR_FROM_INT:
case SPL_INTRIN_FLOAT2INT:
case SPL_INTRIN_INT2FLOAT:
case SPL_INTRIN_INT2PTR:
case SPL_INTRIN_PTR_CAST: {
spl_lang_type_id_t src_lang = sema_infer(sema, vec_at(*args, 0));
if (!src_lang)
@@ -959,8 +959,8 @@ static spl_lang_type_id_t sema_intrin_call(spl_sema_t *sema, spl_ast_node_t *n,
n->resolved_lang_tid = dst_lang;
return dst_lang;
}
case SPL_INTRIN_INT_FROM_BOOL:
case SPL_INTRIN_INT_FROM_PTR: {
case SPL_INTRIN_BOOL2INT:
case SPL_INTRIN_PTR2INT: {
sema_infer(sema, vec_at(*args, 0));
if (nargs >= 2) {
spl_lang_type_id_t dst = sema_infer(sema, vec_at(*args, 1));
@@ -973,6 +973,53 @@ static spl_lang_type_id_t sema_intrin_call(spl_sema_t *sema, spl_ast_node_t *n,
n->resolved_lang_tid = r;
return r;
}
case SPL_INTRIN_ENUM2INT: {
spl_lang_type_id_t src = sema_infer(sema, vec_at(*args, 0));
if (!src)
return 0;
spl_lang_type_node_t *sn = spl_lang_type_node(sema->type, src);
if (!sn || sn->kind != SPL_LANG_TYPE_ENUM) {
spl_diag_error(sema->diag, SPL_DIAG_KIND_TYPE_MISMATCH, &n->dbg,
"@enum2int requires an enum operand");
return 0;
}
spl_type_node_t *sir = spl_type_node(&sema->type->ir, sn->ir_type_id);
if (!sir || !sir->agg_type.tag_type) {
spl_diag_error(sema->diag, SPL_DIAG_KIND_INTERNAL, &n->dbg,
"@enum2int: enum has no tag type");
return 0;
}
spl_lang_type_id_t tag = sema_lang_from_ir(sema, sir->agg_type.tag_type);
n->resolved_lang_tid = tag;
return tag;
}
case SPL_INTRIN_FIELD_COUNT: {
if (!sema_infer_type_context(sema, vec_at(*args, 0)))
return 0;
return spl_lang_make_int(sema->type, sizeof(void *) * 8, 0);
}
case SPL_INTRIN_OFFSETOF: {
spl_lang_type_id_t agg_lang = sema_infer_type_context(sema, vec_at(*args, 0));
if (!agg_lang)
return 0;
spl_type_id_t agg_ir = spl_lang_type_get_ir_type(sema->type, agg_lang);
spl_ast_node_t *fnode = spl_ast_node(sema->ast, vec_at(*args, 1));
if (!fnode)
return 0;
if (fnode->kind == SPL_AST_EXPR_IDENT) {
usize idx = 0;
if (!spl_type_agg_member_idx(&sema->type->ir, agg_ir, fnode->ident.name, &idx)) {
spl_diag_error(sema->diag, SPL_DIAG_KIND_NO_FIELD, &n->dbg, "no field `%s`",
fnode->ident.name);
return 0;
}
} else if (fnode->kind != SPL_AST_EXPR_INT_LIT) {
spl_diag_error(sema->diag, SPL_DIAG_KIND_TYPE_MISMATCH, &n->dbg,
"@offsetof expects a field name or integer index");
return 0;
}
return spl_lang_make_int(sema->type, sizeof(void *) * 8, 0);
}
default:
UNREACHABLE();
}
@@ -2718,11 +2765,12 @@ static spl_lang_type_id_t sema_infer(spl_sema_t *sema, spl_ast_node_ref_t ref) {
return 0;
}
void spl_sema_init(spl_sema_t *sema, spl_ast_t *ast, spl_lang_type_t *type, spl_scope_t *scope,
spl_attr_t *attr) {
void spl_sema_init(spl_sema_t *sema, spl_ast_t *ast, spl_lang_type_t *type, spl_layout_t *layout,
spl_scope_t *scope, spl_attr_t *attr) {
Assert(sema != NULL && ast != NULL && type != NULL && scope != NULL && attr != NULL);
sema->ast = ast;
sema->type = type;
sema->layout = layout;
sema->scope = scope;
sema->current_fn_ret_tid = 0;
sema->current_aggregate_lang = 0;