stage1 实现更多ast2ir 修复bug 提供内置操作

This commit is contained in:
zzy committed 2026-09-11 19:26:48 +08:00
1 parent ab6e99c958
commit 49ccdec3dd
10 files changed
+396 -76

No files matched your search

+96 -19
View File
@@ -1,4 +1,5 @@
#include "spl_sema.h"
#include "spl_intrin.h"
#include "spl_type.h"
void spl_scope_init(spl_scope_t *scope) {
@@ -52,6 +53,10 @@ bool spl_scope_find(spl_scope_t *scope, const char *name, spl_symbol_t *out) {
return false;
}
static spl_lang_type_id_t sema_parse(spl_sema_t *sema, spl_ast_node_ref_t ref);
static spl_lang_type_id_t sema_intrin_call(spl_sema_t *sema, spl_ast_node_t *n, spl_intrin_t in);
static spl_lang_type_id_t sema_intrin_field(spl_sema_t *sema, spl_ast_node_t *n, spl_intrin_t in);
static inline void sema_push_scope(spl_sema_t *sema) {
spl_scope_id_t new_scope = spl_scope_alloc(sema->scope);
sema->store_scope = sema->scope->current_scope;
@@ -170,6 +175,67 @@ static void sema_collect(spl_sema_t *sema, spl_ast_node_ref_t ref) {
}
}
static spl_lang_type_id_t sema_parse(spl_sema_t *sema, spl_ast_node_ref_t ref);
static spl_lang_type_id_t sema_intrin_call(spl_sema_t *sema, spl_ast_node_t *n, spl_intrin_t in) {
const spl_intrin_info_t *info = spl_intrin_info(in);
usize nargs = vec_size(n->call.args);
if ((int)nargs < info->min_args || (info->max_args >= 0 && (int)nargs > info->max_args)) {
SPL_ERROR(&n->dbg, "`%s` expects %d..%d args, got %zu", info->name, info->min_args,
info->max_args, nargs);
sema->error_count++;
return 0;
}
switch (in) {
case SPL_INTRIN_SIZEOF:
case SPL_INTRIN_ALIGNOF: {
spl_ast_node_ref_t arg_ref = vec_at(n->call.args, 0);
spl_ast_node_t *arg = spl_ast_node(sema->ast, arg_ref);
if (!arg || !(arg->kind == SPL_AST_TYPE_PATH || arg->kind == SPL_AST_TYPE_POINTER ||
arg->kind == SPL_AST_TYPE_ARRAY || arg->kind == SPL_AST_TYPE_SLICE ||
arg->kind == SPL_AST_TYPE_FN || arg->kind == SPL_AST_TYPE_PAREN)) {
SPL_ERROR(&n->dbg, "`%s` expects a type argument", info->name);
sema->error_count++;
return 0;
}
sema_parse(sema, arg_ref);
return spl_lang_make_int(sema->type, sizeof(void *) * 8, 0);
}
case SPL_INTRIN_ASSERT: {
spl_lang_type_id_t cond = sema_parse(sema, vec_at(n->call.args, 0));
spl_lang_type_id_t b = spl_lang_make_bool(sema->type);
if (spl_lang_type_coerce_to(sema->type, b, cond) == 0) {
SPL_ERROR(&n->dbg, "`@assert` condition must be bool");
sema->error_count++;
}
if (nargs == 2)
sema_parse(sema, vec_at(n->call.args, 1));
return spl_lang_make_unit(sema->type);
}
default:
UNREACHABLE();
}
return 0;
}
static spl_lang_type_id_t sema_intrin_field(spl_sema_t *sema, spl_ast_node_t *n, spl_intrin_t in) {
const spl_intrin_info_t *info = spl_intrin_info(in);
switch (info->result) {
case SPL_INTRIN_RESULT_USIZE:
return spl_lang_make_int(sema->type, sizeof(void *) * 8, 0);
case SPL_INTRIN_RESULT_BOOL:
return spl_lang_make_bool(sema->type);
case SPL_INTRIN_RESULT_UNIT:
return spl_lang_make_unit(sema->type);
default:
UNREACHABLE();
}
(void)n;
return 0;
}
static spl_lang_type_id_t sema_parse(spl_sema_t *sema, spl_ast_node_ref_t ref) {
if (ref == 0)
return 0;
@@ -268,31 +334,33 @@ static spl_lang_type_id_t sema_parse(spl_sema_t *sema, spl_ast_node_ref_t ref) {
sema->type, tk, &members, spl_type_builder_int(sema->type, 32, 1), layout);
vec_free(members);
// 创建语言级节点
spl_lang_type_node_t lang_node = {0};
spl_lang_type_kind_t lk;
switch (tk) {
case SPL_TYPE_STRUCT:
lang_node.kind = SPL_LANG_TYPE_STRUCT;
lk = SPL_LANG_TYPE_STRUCT;
break;
case SPL_TYPE_UNION:
lang_node.kind = SPL_LANG_TYPE_UNION;
lk = SPL_LANG_TYPE_UNION;
break;
case SPL_TYPE_ENUM:
lang_node.kind = SPL_LANG_TYPE_ENUM;
lk = SPL_LANG_TYPE_ENUM;
break;
case SPL_TYPE_SHAPE:
lang_node.kind = SPL_LANG_TYPE_SHAPE;
lk = SPL_LANG_TYPE_SHAPE;
break;
default:
lk = SPL_LANG_TYPE_STRUCT;
break;
}
lang_node.ir_type_id = agg_ir;
vec_push(sema->type->lang_table, lang_node);
spl_lang_type_id_t agg_lang = vec_size(sema->type->lang_table) - 1;
spl_def_resolve(sema->type, n->resolved_def_id, agg_lang);
n->resolved_type_id = agg_lang; // 存储 lang_id
// 处理聚合内部的函数声明
spl_lang_type_node_t lang_node = {0};
lang_node.kind = lk;
lang_node.ir_type_id = agg_ir;
spl_lang_type_id_t agg_lang = spl_lang_node_push(sema->type, &lang_node);
spl_def_resolve(sema->type, n->resolved_def_id, agg_lang);
n->resolved_type_id = agg_lang;
/* 聚合内部函数:方法后续单独处理,这里暂只做函数体的语义解析 */
for (usize i = 0; i < vec_size(te->type_aggregate.members); ++i) {
spl_ast_node_t *mn = spl_ast_node(sema->ast, vec_at(te->type_aggregate.members, i));
if (mn && mn->kind == SPL_AST_FN_DECL) {
@@ -302,7 +370,7 @@ static spl_lang_type_id_t sema_parse(spl_sema_t *sema, spl_ast_node_ref_t ref) {
} else {
spl_lang_type_id_t tid = sema_parse(sema, n->type_decl.type_expr);
spl_def_resolve(sema->type, n->resolved_def_id, tid);
n->resolved_type_id = tid; // 存储 lang_id
n->resolved_type_id = tid;
}
break;
}
@@ -630,6 +698,16 @@ static spl_lang_type_id_t sema_parse(spl_sema_t *sema, spl_ast_node_ref_t ref) {
}
case SPL_AST_EXPR_CALL: {
spl_ast_node_t *callee = spl_ast_node(sema->ast, n->call.callee);
if (callee && callee->kind == SPL_AST_EXPR_IDENT) {
spl_intrin_t in = spl_intrin_lookup_call(callee->ident.name);
if (in != SPL_INTRIN_NONE) {
spl_lang_type_id_t t = sema_intrin_call(sema, n, in);
n->resolved_type_id = t;
return t;
}
}
spl_lang_type_id_t callee_tid = sema_parse(sema, n->call.callee);
spl_lang_type_node_t *fn = spl_lang_type_node(sema->type, callee_tid);
if (!fn || fn->kind != SPL_LANG_TYPE_FN) {
@@ -702,12 +780,11 @@ static spl_lang_type_id_t sema_parse(spl_sema_t *sema, spl_ast_node_ref_t ref) {
if (!obj_node)
return 0;
// 内建字段:数组/切片的 len
if ((obj_node->kind == SPL_LANG_TYPE_ARRAY || obj_node->kind == SPL_LANG_TYPE_SLICE) &&
strcmp(n->field.field, "len") == 0) {
spl_lang_type_id_t usize_tid = spl_lang_make_int(sema->type, sizeof(void *) * 8, 0);
n->resolved_type_id = usize_tid;
return usize_tid;
spl_intrin_t in = spl_intrin_lookup_field(obj_node->kind, n->field.field);
if (in != SPL_INTRIN_NONE) {
spl_lang_type_id_t t = sema_intrin_field(sema, n, in);
n->resolved_type_id = t;
return t;
}
// 自动解引用