stage2 提供近乎完整的功能但出现严重性能问题 添加stage0的原生性能记录 stage1添加更多内置函数 nob重构代码使其更加健壮
This commit is contained in:
1 parent
b5a7a811b3
commit
e02b0c633a
35 files changed
+14018
-216
No files matched your search
@@ -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:
|
||||
|
||||
@@ -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]);
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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;
|
||||
|
||||
Reference in new issue
Block a user