stage2 更多底层函数 stage1 layout正确使用 内置函数重新编写
This commit is contained in:
1 parent
fb0ff9b663
commit
4141e7d574
15 files changed
+2588
-122
No files matched your search
+55
-7
@@ -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;
|
||||
|
||||
Reference in new issue
Block a user