stage1 支持聚合类型方法

This commit is contained in:
zzy committed 2026-09-14 15:36:43 +08:00
1 parent 9bdb7f892e
commit 5073c2b3ea
10 files changed
+387 -148

No files matched your search

+43 -46
View File
@@ -279,11 +279,14 @@ static int can_start_statement(spl_tok_type_t t) {
}
}
static void parse_tag_list(parser_t *p, spl_ast_node_ref_vec_t *out, int is_external) {
static void parse_tag_list(parser_t *p, spl_ast_node_ref_vec_t *out, int is_external,
int allow_at) {
while (!p->failed) {
const spl_tok_t *t = peek(p);
if (!t || (t->type != TOK_AT && t->type != TOK_SHARP))
return;
if (!allow_at && t->type == TOK_AT)
return;
int is_at = (t->type == TOK_AT);
advance(p);
@@ -370,7 +373,7 @@ static void parse_param_list(parser_t *p, spl_ast_node_ref_vec_t *out) {
static spl_ast_node_ref_t parse_param_decl_impl(parser_t *p) {
spl_ast_node_ref_vec_t attr_list;
vec_init(attr_list);
parse_tag_list(p, &attr_list, 0);
parse_tag_list(p, &attr_list, 0, 1);
const spl_tok_t *name = peek(p);
if (!name || (name->type != TOK_IDENT && name->type != KW_UNDERSCORE)) {
@@ -386,11 +389,13 @@ static spl_ast_node_ref_t parse_param_decl_impl(parser_t *p) {
}
advance(p);
parse_tag_list(p, &attr_list, 0, 0);
spl_ast_node_ref_t type_expr = parse_type_expr(p);
spl_ast_node_ref_t ref = new_node(p, SPL_AST_PARAM_DECL, name);
spl_ast_node_t *param = node_at(p->ast, ref);
MOVE_VEC(param->param_decl.attr_list, attr_list);
SET_STR_FIELD(p->ast, param->param_decl.name, name); // 若为下划线则存储 "_"
SET_STR_FIELD(p->ast, param->param_decl.name, name);
param->param_decl.type_expr = type_expr;
return ref;
}
@@ -545,6 +550,7 @@ static spl_ast_node_ref_t parse_member_decl(parser_t *p, spl_ast_node_ref_vec_t
const spl_tok_t *t = peek(p);
if (t && t->type == TOK_COLON) {
advance(p);
parse_tag_list(p, &tag_list, 0, 0);
type_expr = parse_type_expr(p);
t = peek(p);
if (t && t->type == TOK_ASSIGN) {
@@ -592,7 +598,7 @@ static spl_ast_node_ref_t parse_comptime_decl(parser_t *p) {
static spl_ast_node_ref_t parse_container_declaration(parser_t *p) {
spl_ast_node_ref_vec_t tag_list;
vec_init(tag_list);
parse_tag_list(p, &tag_list, 0); /* 只解析普通 tag */
parse_tag_list(p, &tag_list, 0, 0); /* 只解析普通 tag */
const spl_tok_t *t = peek(p);
if (!t || t->type == TOK_EOF) {
@@ -738,20 +744,14 @@ static spl_ast_node_ref_t parse_match_pattern(parser_t *p) {
}
static spl_ast_node_ref_t parse_type_base(parser_t *p) {
spl_ast_node_ref_vec_t tag_list;
vec_init(tag_list);
parse_tag_list(p, &tag_list, 0);
const spl_tok_t *bt = peek(p);
if (!bt) {
vec_free(tag_list);
SPL_FATAL(bt, "expected type");
return 0;
}
/* 函数类型 */
if (bt->type == KW_FN) {
vec_free(tag_list);
advance(p);
const spl_tok_t *t = peek(p);
if (!t || t->type != TOK_L_PAREN) {
@@ -794,7 +794,6 @@ static spl_ast_node_ref_t parse_type_base(parser_t *p) {
/* 聚合类型:struct / union / enum / shape */
if (bt->type == KW_STRUCT || bt->type == KW_UNION || bt->type == KW_ENUM ||
bt->type == KW_SHAPE) {
vec_free(tag_list); /* 聚合类型不使用 tag_list */
const char *kind_name = (bt->type == KW_STRUCT) ? "struct"
: (bt->type == KW_UNION) ? "union"
: (bt->type == KW_ENUM) ? "enum"
@@ -865,7 +864,6 @@ static spl_ast_node_ref_t parse_type_base(parser_t *p) {
spl_ast_node_t *tp = node_at(p->ast, ref);
SET_STR_FIELD(p->ast, tp->type_path.name, bt);
vec_init(tp->type_path.generic_args);
vec_free(tag_list);
return ref;
}
@@ -885,12 +883,10 @@ static spl_ast_node_ref_t parse_type_base(parser_t *p) {
}
advance(p);
}
vec_free(tag_list);
return ref;
}
if (bt->type == TOK_AT || bt->type == TOK_SHARP) {
vec_free(tag_list);
return parse_type_comptime_call(p);
}
@@ -900,11 +896,9 @@ static spl_ast_node_ref_t parse_type_base(parser_t *p) {
spl_ast_node_t *tp = node_at(p->ast, ref);
SET_STR_FIELD(p->ast, tp->type_path.name, bt);
vec_init(tp->type_path.generic_args);
vec_free(tag_list);
return ref;
}
vec_free(tag_list);
SPL_FATAL(bt, "unrecognized type");
return 0;
}
@@ -917,26 +911,26 @@ static spl_ast_node_ref_t parse_type_comptime_call(parser_t *p) {
const spl_tok_t *name = peek(p);
if (!name || name->type != TOK_IDENT) {
SPL_FATAL(name, "expected comptime call name");
SPL_FATAL(name, "expected comptime name");
return 0;
}
advance(p);
spl_ast_node_ref_vec_t args;
vec_init(args);
const spl_tok_t *t = peek(p);
if (!t || t->type != TOK_L_PAREN) {
SPL_FATAL(t, "expected '(' in comptime call");
return 0;
if (t && t->type == TOK_L_PAREN) {
advance(p);
args = parse_expr_list(p);
t = peek(p);
if (!t || t->type != TOK_R_PAREN) {
SPL_FATAL(t, "expected ')' in comptime type");
vec_free(args);
return 0;
}
advance(p);
}
advance(p);
spl_ast_node_ref_vec_t args = parse_expr_list(p);
t = peek(p);
if (!t || t->type != TOK_R_PAREN) {
SPL_FATAL(t, "expected ')' in comptime call");
return 0;
}
advance(p);
spl_ast_node_ref_t ref = new_node(p, SPL_AST_TYPE_COMPTIME_CALL, start);
spl_ast_node_t *cc = node_at(p->ast, ref);
@@ -1606,31 +1600,34 @@ static spl_ast_node_ref_t parse_comptime_call(parser_t *p) {
const spl_tok_t *name = peek(p);
if (!name || name->type != TOK_IDENT) {
SPL_FATAL(name, "expected comptime call name");
SPL_FATAL(name, "expected comptime name");
return 0;
}
advance(p);
spl_ast_node_ref_vec_t args;
vec_init(args);
int has_paren = 0;
const spl_tok_t *t = peek(p);
if (!t || t->type != TOK_L_PAREN) {
SPL_FATAL(t, "expected '(' in comptime call");
return 0;
if (t && t->type == TOK_L_PAREN) {
has_paren = 1;
advance(p);
args = parse_expr_list(p);
t = peek(p);
if (!t || t->type != TOK_R_PAREN) {
SPL_FATAL(t, "expected ')' in comptime call");
vec_free(args);
return 0;
}
advance(p);
}
advance(p);
spl_ast_node_ref_vec_t args = parse_expr_list(p);
t = peek(p);
if (!t || t->type != TOK_R_PAREN) {
SPL_FATAL(t, "expected ')' in comptime call");
return 0;
}
advance(p);
spl_ast_node_ref_t ref = new_node(p, SPL_AST_EXPR_COMPTIME_CALL, start);
spl_ast_node_t *cc = node_at(p->ast, ref);
SET_STR_FIELD(p->ast, cc->comptime_call.name, name);
cc->comptime_call.args = args;
(void)has_paren;
return ref;
}
@@ -2082,7 +2079,7 @@ static spl_ast_node_ref_t parse_statement(parser_t *p) {
case KW_TYPE: {
spl_ast_node_ref_vec_t tag_list;
vec_init(tag_list);
parse_tag_list(p, &tag_list, 0); // 解析声明前的普通 tag
parse_tag_list(p, &tag_list, 0, 0); // 解析声明前的普通 tag
spl_ast_node_ref_t decl;
if (t->type == KW_VAR)
@@ -2214,7 +2211,7 @@ void spl_ast_parse(spl_ast_t *ast) {
p.pos = save_pos;
}
if (t2 && t2->type == TOK_NOT) {
parse_tag_list(&p, &external_tags, 1);
parse_tag_list(&p, &external_tags, 1, 1);
continue;
}
}