stage2 提供近乎完整的功能但出现严重性能问题 添加stage0的原生性能记录 stage1添加更多内置函数 nob重构代码使其更加健壮

This commit is contained in:
zzy committed 2026-09-19 18:08:43 +08:00
1 parent b5a7a811b3
commit e02b0c633a
35 files changed
+14018 -216

No files matched your search

+72
View File
@@ -72,6 +72,9 @@ static spl_ir_node_ref_t ast2ir_intrin_call(spl_ast2ir_t *a, spl_ast_node_t *n,
spl_ast_node_ref_vec_t *args);
static spl_ir_node_ref_t ast2ir_intrin_field(spl_ast2ir_t *a, spl_ast_node_t *n, spl_intrin_t in);
static spl_ir_node_ref_t ast2ir_intrin_len(spl_ast2ir_t *a, spl_ast_node_t *n);
static spl_ir_node_ref_t ast2ir_intrin_pos(spl_ast2ir_t *a, spl_ast_node_t *n, int which);
static spl_ir_node_ref_t ast2ir_intrin_file_name(spl_ast2ir_t *a, spl_ast_node_t *n);
static spl_ir_node_ref_t ast2ir_intrin_fn_name(spl_ast2ir_t *a, spl_ast_node_t *n);
static spl_ir_node_ref_t emit_zero_value(spl_ast2ir_t *a, spl_type_id_t tid) {
spl_type_node_t *tn = spl_type_node(&a->sema->type->ir, tid);
@@ -461,6 +464,14 @@ static spl_ir_node_ref_t ast2ir_intrin_call(spl_ast2ir_t *a, spl_ast_node_t *n,
case SPL_INTRIN_INT2PTR:
case SPL_INTRIN_PTR_CAST:
return ast2ir_intrin_cast(a, n, in, args);
case SPL_INTRIN_LINE:
return ast2ir_intrin_pos(a, n, 0);
case SPL_INTRIN_COL:
return ast2ir_intrin_pos(a, n, 1);
case SPL_INTRIN_FILE_NAME:
return ast2ir_intrin_file_name(a, n);
case SPL_INTRIN_FN_NAME:
return ast2ir_intrin_fn_name(a, n);
case SPL_INTRIN_BREAKPOINT:
return spl_ir_builder_dbg_breakpoint(a->ir);
default:
@@ -469,6 +480,67 @@ static spl_ir_node_ref_t ast2ir_intrin_call(spl_ast2ir_t *a, spl_ast_node_t *n,
return 0;
}
/* @line() / @col():把调用点位置降为 usize 常量。which: 0=line, 1=col。 */
static spl_ir_node_ref_t ast2ir_intrin_pos(spl_ast2ir_t *a, spl_ast_node_t *n, int which) {
spl_lang_type_id_t usize_lang = spl_lang_make_int(a->sema->type, sizeof(void *) * 8, 0);
spl_type_id_t usize_ir = to_ir_type(a, usize_lang);
usize v = which == 0 ? (usize)n->dbg.line : (usize)n->dbg.col;
return spl_ir_builder_type_const_int(a->ir, usize_ir, v);
}
/* @file_name():把调用点所在文件路径降为 []u8(同字符串字面量的构造方式)。 */
static spl_ir_node_ref_t ast2ir_intrin_file_name(spl_ast2ir_t *a, spl_ast_node_t *n) {
const char *fname = n->dbg.fname ? n->dbg.fname : "?";
usize len = strlen(fname);
spl_lang_type_id_t u8_lang = spl_lang_make_int(a->sema->type, 8, 0);
spl_type_id_t u8_ir = to_ir_type(a, u8_lang);
spl_type_id_t ptr_u8_ir = spl_type_builder_ptr(&a->sema->type->ir, u8_ir);
spl_lang_type_id_t usize_lang = spl_lang_make_int(a->sema->type, sizeof(void *) * 8, 0);
spl_type_id_t usize_ir = to_ir_type(a, usize_lang);
spl_lang_type_id_t arr_lang = spl_lang_make_array(a->sema->type, u8_lang, len);
spl_type_id_t arr_ir = to_ir_type(a, arr_lang);
spl_ir_node_ref_t raw =
spl_ir_builder_type_const_bytes(a->ir, arr_ir, (void *)fname, len);
spl_ir_node_ref_t ptr = spl_ir_builder_mem_global_alloc(a->ir, ptr_u8_ir, raw);
spl_ir_node_ref_t len_c = spl_ir_builder_type_const_int(a->ir, usize_ir, len);
spl_type_id_t slice_ir = node_ir(a, n);
spl_ir_node_ref_t node = spl_ir_builder_agg_construct(a->ir, slice_ir);
spl_ir_builder_agg_construct_field(a->ir, node, ptr);
spl_ir_builder_agg_construct_field(a->ir, node, len_c);
return node;
}
/* @fn_name():把当前函数名降为 []u8(同字符串字面量的构造方式)。 */
static spl_ir_node_ref_t ast2ir_intrin_fn_name(spl_ast2ir_t *a, spl_ast_node_t *n) {
const char *name = "?";
spl_ir_func_t *f = spl_ir_func(&a->ir->ir, a->ir->current_fn);
if (f && f->name)
name = f->name;
usize len = strlen(name);
spl_lang_type_id_t u8_lang = spl_lang_make_int(a->sema->type, 8, 0);
spl_type_id_t u8_ir = to_ir_type(a, u8_lang);
spl_type_id_t ptr_u8_ir = spl_type_builder_ptr(&a->sema->type->ir, u8_ir);
spl_lang_type_id_t usize_lang = spl_lang_make_int(a->sema->type, sizeof(void *) * 8, 0);
spl_type_id_t usize_ir = to_ir_type(a, usize_lang);
spl_lang_type_id_t arr_lang = spl_lang_make_array(a->sema->type, u8_lang, len);
spl_type_id_t arr_ir = to_ir_type(a, arr_lang);
spl_ir_node_ref_t raw =
spl_ir_builder_type_const_bytes(a->ir, arr_ir, (void *)name, len);
spl_ir_node_ref_t ptr = spl_ir_builder_mem_global_alloc(a->ir, ptr_u8_ir, raw);
spl_ir_node_ref_t len_c = spl_ir_builder_type_const_int(a->ir, usize_ir, len);
spl_type_id_t slice_ir = node_ir(a, n);
spl_ir_node_ref_t node = spl_ir_builder_agg_construct(a->ir, slice_ir);
spl_ir_builder_agg_construct_field(a->ir, node, ptr);
spl_ir_builder_agg_construct_field(a->ir, node, len_c);
return node;
}
static spl_ir_node_ref_t ast2ir_intrin_field(spl_ast2ir_t *a, spl_ast_node_t *n, spl_intrin_t in) {
switch (in) {
case SPL_INTRIN_LEN:
+8
View File
@@ -40,6 +40,14 @@ static const spl_intrin_info_t g_intrin_table[] = {
SPL_INTRIN_RESULT_USIZE},
[SPL_INTRIN_FIELD_COUNT] = {"@field_count", SPL_INTRIN_FIELD_COUNT, SPL_INTRIN_FORM_CALL, 1, 1,
SPL_INTRIN_RESULT_USIZE},
[SPL_INTRIN_FILE_NAME] = {"@file_name", SPL_INTRIN_FILE_NAME, SPL_INTRIN_FORM_CALL, 0, 0,
SPL_INTRIN_RESULT_USIZE},
[SPL_INTRIN_LINE] = {"@line", SPL_INTRIN_LINE, SPL_INTRIN_FORM_CALL, 0, 0,
SPL_INTRIN_RESULT_USIZE},
[SPL_INTRIN_COL] = {"@col", SPL_INTRIN_COL, SPL_INTRIN_FORM_CALL, 0, 0,
SPL_INTRIN_RESULT_USIZE},
[SPL_INTRIN_FN_NAME] = {"@fn_name", SPL_INTRIN_FN_NAME, SPL_INTRIN_FORM_CALL, 0, 0,
SPL_INTRIN_RESULT_USIZE},
};
static const usize g_intrin_count = sizeof(g_intrin_table) / sizeof(g_intrin_table[0]);
+5
View File
@@ -25,6 +25,11 @@ typedef enum {
SPL_INTRIN_ENUM2INT,
SPL_INTRIN_OFFSETOF,
SPL_INTRIN_FIELD_COUNT,
/* 调用点位置信息(供日志/性能分析库使用) */
SPL_INTRIN_FILE_NAME,
SPL_INTRIN_LINE,
SPL_INTRIN_COL,
SPL_INTRIN_FN_NAME,
} spl_intrin_t;
typedef enum {
+3 -2
View File
@@ -203,8 +203,9 @@ static void ir_dump_node(const spl_type_t *ty, spl_ir_node_t *n) {
printf(" float=%f", n->type_const.float_lit);
} else if (t && t->kind == SPL_TYPE_FN) {
printf(" fn#%zu", n->type_const.fn);
// } else if (t && t->kind == SPL_TYPE_PTR) {
// printf(" str=\"%s\"", n->type_const.cstr_lit ? n->type_const.cstr_lit : "?");
} else if (t && t->kind == SPL_TYPE_ARRAY) {
/* 字节常量:不打印宿主指针(不确定),只标记 bytes。 */
printf(" bytes");
} else if (t && t->kind == SPL_TYPE_INT && t->int_type.bits == 8) {
printf(" char='%c'", n->type_const.ch_lit);
} else {
+33 -3
View File
@@ -1020,6 +1020,16 @@ static spl_lang_type_id_t sema_intrin_call(spl_sema_t *sema, spl_ast_node_t *n,
}
return spl_lang_make_int(sema->type, sizeof(void *) * 8, 0);
}
case SPL_INTRIN_FILE_NAME:
case SPL_INTRIN_FN_NAME: {
spl_lang_type_id_t u8 = spl_lang_make_int(sema->type, 8, 0);
spl_lang_type_id_t slice = spl_lang_make_slice(sema->type, u8);
n->resolved_lang_tid = slice;
return slice;
}
case SPL_INTRIN_LINE:
case SPL_INTRIN_COL:
return spl_lang_make_int(sema->type, sizeof(void *) * 8, 0);
default:
UNREACHABLE();
}
@@ -2843,16 +2853,36 @@ void spl_sema_run(spl_sema_t *sema) {
spl_sema_run_module(sema, root->root.members);
}
typedef struct {
const char *key;
spl_symbol_t sym;
} spl_sema_sym_t;
static int spl_sema_sym_cmp(const void *a, const void *b) {
return strcmp(((const spl_sema_sym_t *)a)->key, ((const spl_sema_sym_t *)b)->key);
}
void spl_sema_dump(spl_sema_t *sema) {
printf("Scopes:\n");
for (usize i = 1; i < vec_size(sema->scope->scopes); ++i) {
spl_scope_node_t *scope = &vec_at(sema->scope->scopes, i);
printf("scope[%zu] parent=%zu\n", i, scope->parent);
/* 按符号名排序输出:与哈希表内部布局解耦,保证确定顺序。 */
usize nsyms = scope->symbols.size;
spl_sema_sym_t *arr = nsyms ? malloc(nsyms * sizeof(*arr)) : NULL;
usize k = 0;
map_for(scope->symbols, j) {
spl_symbol_t *symbol = &unsafe_map_at(scope->symbols, j).val;
printf(" %s -> def`%s`#%zu\n", unsafe_map_at(scope->symbols, j).key, symbol->name,
symbol->node);
arr[k].key = unsafe_map_at(scope->symbols, j).key;
arr[k].sym = unsafe_map_at(scope->symbols, j).val;
k++;
}
if (arr && nsyms > 1)
qsort(arr, nsyms, sizeof(*arr), spl_sema_sym_cmp);
for (k = 0; k < nsyms; ++k) {
printf(" %s -> def`%s`#%zu\n", arr[k].key, arr[k].sym.name, arr[k].sym.node);
}
free(arr);
}
printf("LangTypeTable:\n");
for (usize i = 1; i < vec_size(sema->type->lang_table); ++i) {
+31 -4
View File
@@ -81,15 +81,18 @@ static void dump_tokens(spl_tok_vec_t toks) {
vec_free(toks);
}
/* 折叠重复分隔符并去掉 "." 路径分量,使同一模块的 import 解析结果唯一。
就地重写,'\' 统一成 '/';保留前导分隔符(绝对路径)。 */
/* 折叠重复分隔符、解析 "." 与 ".." 路径分量,使同一模块的 import 解析结果唯一。
就地重写,'\' 统一成 '/';保留前导分隔符(绝对路径)。
".." 会弹出上一个分量;无分量可弹时按相对语义保留(绝对根则忽略)。 */
static void normalize_import_path(char *p) {
usize n = strlen(p);
char *out = malloc(n + 1);
if (!out)
return;
char *base = out;
char *w = out;
if (p[0] == '/' || p[0] == '\\')
int has_root = (p[0] == '/' || p[0] == '\\');
if (has_root)
*w++ = '/';
char *r = p;
@@ -104,7 +107,31 @@ static void normalize_import_path(char *p) {
usize len = (usize)(r - seg);
if (len == 1 && seg[0] == '.')
continue;
if (w != out && w[-1] != '/')
if (len == 2 && seg[0] == '.' && seg[1] == '.') {
if (w == base + (has_root ? 1 : 0)) {
if (!has_root) {
*w++ = '.';
*w++ = '.';
}
} else {
char *q = w;
while (q > base && q[-1] != '/')
q--;
usize sl = (usize)(w - q);
if (sl == 2 && q[0] == '.' && q[1] == '.') {
*w++ = '.';
*w++ = '.';
} else {
if (q > base && q[-1] == '/')
q--;
w = q;
if (w == base && has_root)
w = base + 1;
}
}
continue;
}
if (w != base && w[-1] != '/')
*w++ = '/';
memcpy(w, seg, len);
w += len;