stage1 实现更多ast2ir 修复bug 提供内置操作
This commit is contained in:
1 parent
ab6e99c958
commit
49ccdec3dd
10 files changed
+396
-76
No files matched your search
+96
-19
@@ -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;
|
||||
}
|
||||
|
||||
// 自动解引用
|
||||
|
||||
Reference in new issue
Block a user