stage1 支持聚合类型方法
This commit is contained in:
1 parent
9bdb7f892e
commit
5073c2b3ea
10 files changed
+387
-148
No files matched your search
+43
-46
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user