stage1 重写进行代码设计并重构 提供diag替换老旧错误处理
This commit is contained in:
1 parent
7cbe2d2b9a
commit
e4347cc3ea
14 files changed
+983
-526
No files matched your search
+104
-99
@@ -59,12 +59,34 @@ const char *spl_unary_op_name(spl_unary_op_t op) {
|
||||
|
||||
typedef struct {
|
||||
spl_ast_t *ast;
|
||||
spl_diag_t *diag;
|
||||
usize pos;
|
||||
int failed;
|
||||
int stop_as;
|
||||
int stop_agg;
|
||||
} parser_t;
|
||||
|
||||
/* token -> dbg 位置;tok 可为 NULL */
|
||||
static spl_dbg_node_t tok_to_dbg(const spl_tok_t *t) {
|
||||
spl_dbg_node_t d = {0};
|
||||
if (t) {
|
||||
d.fname = t->fname;
|
||||
d.line = (int)t->line;
|
||||
d.col = (int)t->col;
|
||||
}
|
||||
return d;
|
||||
}
|
||||
|
||||
/* parser 层的 fatal 发射。diag 为 NULL 时静默。
|
||||
* 调用者必须紧跟 return / break,因为 diag_fatal 不终止流程。 */
|
||||
#define PARSE_FATAL(p, kind, tok, ...) \
|
||||
do { \
|
||||
if ((p)->diag) { \
|
||||
spl_dbg_node_t _pd = tok_to_dbg(tok); \
|
||||
spl_diag_fatal((p)->diag, (kind), &_pd, __VA_ARGS__); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
static inline int is_trivia(spl_tok_type_t t) { return t == TOK_ENDLINE || t == TOK_LINE_COMMENT; }
|
||||
|
||||
static inline const spl_tok_t *peek(parser_t *p) {
|
||||
@@ -301,7 +323,7 @@ static void parse_tag_list(parser_t *p, spl_ast_node_ref_vec_t *out, int is_exte
|
||||
if (is_external) {
|
||||
t = peek(p);
|
||||
if (!t || t->type != TOK_NOT) {
|
||||
SPL_FATAL(t, "expected '!' in external tag");
|
||||
PARSE_FATAL(p, SPL_DIAG_KIND_PARSE_EXPECTED, t, "expected '!' in external tag");
|
||||
return;
|
||||
}
|
||||
advance(p);
|
||||
@@ -309,7 +331,7 @@ static void parse_tag_list(parser_t *p, spl_ast_node_ref_vec_t *out, int is_exte
|
||||
|
||||
t = peek(p);
|
||||
if (!t || t->type != TOK_IDENT) {
|
||||
SPL_FATAL(t, "expected tag name");
|
||||
PARSE_FATAL(p, SPL_DIAG_KIND_PARSE_EXPECTED, t, "expected tag name");
|
||||
return;
|
||||
}
|
||||
advance(p);
|
||||
@@ -328,7 +350,7 @@ static void parse_tag_list(parser_t *p, spl_ast_node_ref_vec_t *out, int is_exte
|
||||
node_at(p->ast, ref)->tag_item.args = args;
|
||||
t = peek(p);
|
||||
if (!t || t->type != TOK_R_PAREN) {
|
||||
SPL_FATAL(t, "expected ')' in tag args");
|
||||
PARSE_FATAL(p, SPL_DIAG_KIND_PARSE_EXPECTED, t, "expected ')' in tag args");
|
||||
return;
|
||||
}
|
||||
advance(p);
|
||||
@@ -363,15 +385,9 @@ static void parse_param_list(parser_t *p, spl_ast_node_ref_vec_t *out) {
|
||||
if (peek(p) && peek(p)->type == TOK_COMMA)
|
||||
advance(p);
|
||||
break;
|
||||
// } else if (t->type == KW_VOID) {
|
||||
// advance(p);
|
||||
// t = peek(p);
|
||||
// if (!t || t->type != TOK_R_PAREN) {
|
||||
// SPL_FATAL(t, "expected ')' after void");
|
||||
// }
|
||||
// break;
|
||||
} else {
|
||||
SPL_FATAL(t, "unexpected token in parameter list");
|
||||
PARSE_FATAL(p, SPL_DIAG_KIND_PARSE_UNRECOGNIZED, t,
|
||||
"unexpected token in parameter list");
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -384,14 +400,14 @@ static spl_ast_node_ref_t parse_param_decl_impl(parser_t *p) {
|
||||
|
||||
const spl_tok_t *name = peek(p);
|
||||
if (!name || (name->type != TOK_IDENT && name->type != KW_UNDERSCORE)) {
|
||||
SPL_FATAL(name, "expected parameter name or '_'");
|
||||
PARSE_FATAL(p, SPL_DIAG_KIND_PARSE_EXPECTED, name, "expected parameter name or '_'");
|
||||
return 0;
|
||||
}
|
||||
advance(p);
|
||||
|
||||
const spl_tok_t *t = peek(p);
|
||||
if (!t || t->type != TOK_COLON) {
|
||||
SPL_FATAL(t, "expected ':' in parameter declaration");
|
||||
PARSE_FATAL(p, SPL_DIAG_KIND_PARSE_EXPECTED, t, "expected ':' in parameter declaration");
|
||||
return 0;
|
||||
}
|
||||
advance(p);
|
||||
@@ -415,14 +431,14 @@ static spl_ast_node_ref_t parse_fn_decl(parser_t *p, spl_ast_node_ref_vec_t tag_
|
||||
|
||||
const spl_tok_t *name = peek(p);
|
||||
if (!name || name->type != TOK_IDENT) {
|
||||
SPL_FATAL(name ? name : kw, "expected function name");
|
||||
PARSE_FATAL(p, SPL_DIAG_KIND_PARSE_EXPECTED, name ? name : kw, "expected function name");
|
||||
return 0;
|
||||
}
|
||||
advance(p);
|
||||
|
||||
const spl_tok_t *t = peek(p);
|
||||
if (!t || t->type != TOK_L_PAREN) {
|
||||
SPL_FATAL(t, "expected '(' in function declaration");
|
||||
PARSE_FATAL(p, SPL_DIAG_KIND_PARSE_EXPECTED, t, "expected '(' in function declaration");
|
||||
return 0;
|
||||
}
|
||||
advance(p);
|
||||
@@ -432,7 +448,7 @@ static spl_ast_node_ref_t parse_fn_decl(parser_t *p, spl_ast_node_ref_vec_t tag_
|
||||
parse_param_list(p, ¶ms);
|
||||
t = peek(p);
|
||||
if (!t || t->type != TOK_R_PAREN) {
|
||||
SPL_FATAL(t, "expected ')' in function declaration");
|
||||
PARSE_FATAL(p, SPL_DIAG_KIND_PARSE_EXPECTED, t, "expected ')' in function declaration");
|
||||
return 0;
|
||||
}
|
||||
advance(p);
|
||||
@@ -451,7 +467,8 @@ static spl_ast_node_ref_t parse_fn_decl(parser_t *p, spl_ast_node_ref_vec_t tag_
|
||||
} else if (t && t->type == TOK_SEMICOLON) {
|
||||
advance(p);
|
||||
} else {
|
||||
SPL_FATAL(t, "function declaration must end with ';' or block");
|
||||
PARSE_FATAL(p, SPL_DIAG_KIND_PARSE_UNRECOGNIZED, t,
|
||||
"function declaration must end with ';' or block");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -474,14 +491,14 @@ static spl_ast_node_ref_t parse_type_decl(parser_t *p, spl_ast_node_ref_vec_t ta
|
||||
|
||||
const spl_tok_t *name = peek(p);
|
||||
if (!name || name->type != TOK_IDENT) {
|
||||
SPL_FATAL(name ? name : kw, "expected type name");
|
||||
PARSE_FATAL(p, SPL_DIAG_KIND_PARSE_EXPECTED, name ? name : kw, "expected type name");
|
||||
return 0;
|
||||
}
|
||||
advance(p);
|
||||
|
||||
const spl_tok_t *t = peek(p);
|
||||
if (!t || t->type != TOK_ASSIGN) {
|
||||
SPL_FATAL(t, "expected '=' in type declaration");
|
||||
PARSE_FATAL(p, SPL_DIAG_KIND_PARSE_EXPECTED, t, "expected '=' in type declaration");
|
||||
return 0;
|
||||
}
|
||||
advance(p);
|
||||
@@ -636,7 +653,7 @@ static spl_ast_node_ref_t parse_container_declaration(parser_t *p) {
|
||||
return ref;
|
||||
}
|
||||
default:
|
||||
SPL_FATAL(t, "unrecognized declaration");
|
||||
PARSE_FATAL(p, SPL_DIAG_KIND_PARSE_UNRECOGNIZED, t, "unrecognized declaration");
|
||||
vec_free(tag_list);
|
||||
return 0;
|
||||
}
|
||||
@@ -659,7 +676,8 @@ static spl_ast_node_ref_t parse_var_pattern_atom(parser_t *p) {
|
||||
advance(p);
|
||||
const spl_tok_t *name = peek(p);
|
||||
if (!name || name->type != TOK_IDENT) {
|
||||
SPL_FATAL(name, "expected identifier after '.' in pattern");
|
||||
PARSE_FATAL(p, SPL_DIAG_KIND_PARSE_EXPECTED, name,
|
||||
"expected identifier after '.' in pattern");
|
||||
return 0;
|
||||
}
|
||||
advance(p);
|
||||
@@ -674,7 +692,7 @@ static spl_ast_node_ref_t parse_var_pattern_atom(parser_t *p) {
|
||||
node_at(p->ast, ref)->pattern_dot.sub_pattern = sub;
|
||||
t = peek(p);
|
||||
if (!t || t->type != TOK_R_BRACKET) {
|
||||
SPL_FATAL(t, "expected ']' in pattern");
|
||||
PARSE_FATAL(p, SPL_DIAG_KIND_PARSE_EXPECTED, t, "expected ']' in pattern");
|
||||
return 0;
|
||||
}
|
||||
advance(p);
|
||||
@@ -685,7 +703,7 @@ static spl_ast_node_ref_t parse_var_pattern_atom(parser_t *p) {
|
||||
spl_ast_node_ref_t inner = parse_var_pattern(p);
|
||||
t = peek(p);
|
||||
if (!t || t->type != TOK_R_PAREN) {
|
||||
SPL_FATAL(t, "expected ')' in pattern");
|
||||
PARSE_FATAL(p, SPL_DIAG_KIND_PARSE_EXPECTED, t, "expected ')' in pattern");
|
||||
return 0;
|
||||
}
|
||||
advance(p);
|
||||
@@ -700,7 +718,7 @@ static spl_ast_node_ref_t parse_var_pattern_atom(parser_t *p) {
|
||||
}
|
||||
return ref;
|
||||
} else {
|
||||
SPL_FATAL(t, "unexpected token in pattern");
|
||||
PARSE_FATAL(p, SPL_DIAG_KIND_PARSE_UNRECOGNIZED, t, "unexpected token in pattern");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -753,7 +771,7 @@ static spl_ast_node_ref_t parse_match_pattern(parser_t *p) {
|
||||
static spl_ast_node_ref_t parse_type_base(parser_t *p) {
|
||||
const spl_tok_t *bt = peek(p);
|
||||
if (!bt) {
|
||||
SPL_FATAL(bt, "expected type");
|
||||
PARSE_FATAL(p, SPL_DIAG_KIND_PARSE_EXPECTED, bt, "expected type");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -762,7 +780,7 @@ static spl_ast_node_ref_t parse_type_base(parser_t *p) {
|
||||
advance(p);
|
||||
const spl_tok_t *t = peek(p);
|
||||
if (!t || t->type != TOK_L_PAREN) {
|
||||
SPL_FATAL(t, "expected '(' in function type");
|
||||
PARSE_FATAL(p, SPL_DIAG_KIND_PARSE_EXPECTED, t, "expected '(' in function type");
|
||||
return 0;
|
||||
}
|
||||
advance(p);
|
||||
@@ -785,7 +803,7 @@ static spl_ast_node_ref_t parse_type_base(parser_t *p) {
|
||||
|
||||
t = peek(p);
|
||||
if (!t || t->type != TOK_R_PAREN) {
|
||||
SPL_FATAL(t, "expected ')' in function type");
|
||||
PARSE_FATAL(p, SPL_DIAG_KIND_PARSE_EXPECTED, t, "expected ')' in function type");
|
||||
return 0;
|
||||
}
|
||||
advance(p);
|
||||
@@ -808,7 +826,7 @@ static spl_ast_node_ref_t parse_type_base(parser_t *p) {
|
||||
advance(p);
|
||||
const spl_tok_t *t = peek(p);
|
||||
if (!t || t->type != TOK_L_BRACE) {
|
||||
SPL_FATAL(t, "expected '{' in aggregate type");
|
||||
PARSE_FATAL(p, SPL_DIAG_KIND_PARSE_EXPECTED, t, "expected '{' in aggregate type");
|
||||
return 0;
|
||||
}
|
||||
advance(p);
|
||||
@@ -822,7 +840,7 @@ static spl_ast_node_ref_t parse_type_base(parser_t *p) {
|
||||
while (!p->failed) {
|
||||
t = peek(p);
|
||||
if (!t || t->type == TOK_EOF) {
|
||||
SPL_FATAL(t, "aggregate type missing '}'");
|
||||
PARSE_FATAL(p, SPL_DIAG_KIND_PARSE_EXPECTED, t, "aggregate type missing '}'");
|
||||
return ref;
|
||||
}
|
||||
if (t->type == TOK_R_BRACE) {
|
||||
@@ -862,10 +880,7 @@ static spl_ast_node_ref_t parse_type_base(parser_t *p) {
|
||||
(len == 5 && strncmp(name, "usize", 5) == 0) ||
|
||||
(len == 3 && strncmp(name, "f32", 3) == 0) ||
|
||||
(len == 3 && strncmp(name, "f64", 3) == 0) ||
|
||||
(len == 4 && strncmp(name, "bool", 4) == 0)
|
||||
// (len == 4 && strncmp(name, "void", 4) == 0) ||
|
||||
// (len == 3 && strncmp(name, "any", 3) == 0)
|
||||
) {
|
||||
(len == 4 && strncmp(name, "bool", 4) == 0)) {
|
||||
advance(p);
|
||||
spl_ast_node_ref_t ref = new_node(p, SPL_AST_TYPE_PATH, bt);
|
||||
spl_ast_node_t *tp = node_at(p->ast, ref);
|
||||
@@ -885,7 +900,8 @@ static spl_ast_node_ref_t parse_type_base(parser_t *p) {
|
||||
advance(p);
|
||||
const spl_tok_t *seg = peek(p);
|
||||
if (!seg || seg->type != TOK_IDENT) {
|
||||
SPL_FATAL(seg, "expected identifier after '.' in type path");
|
||||
PARSE_FATAL(p, SPL_DIAG_KIND_PARSE_EXPECTED, seg,
|
||||
"expected identifier after '.' in type path");
|
||||
break;
|
||||
}
|
||||
advance(p);
|
||||
@@ -906,7 +922,7 @@ static spl_ast_node_ref_t parse_type_base(parser_t *p) {
|
||||
return ref;
|
||||
}
|
||||
|
||||
SPL_FATAL(bt, "unrecognized type");
|
||||
PARSE_FATAL(p, SPL_DIAG_KIND_PARSE_UNRECOGNIZED, bt, "unrecognized type");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -918,7 +934,7 @@ 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 name");
|
||||
PARSE_FATAL(p, SPL_DIAG_KIND_PARSE_EXPECTED, name, "expected comptime name");
|
||||
return 0;
|
||||
}
|
||||
advance(p);
|
||||
@@ -932,7 +948,7 @@ static spl_ast_node_ref_t parse_type_comptime_call(parser_t *p) {
|
||||
args = parse_expr_list(p);
|
||||
t = peek(p);
|
||||
if (!t || t->type != TOK_R_PAREN) {
|
||||
SPL_FATAL(t, "expected ')' in comptime type");
|
||||
PARSE_FATAL(p, SPL_DIAG_KIND_PARSE_EXPECTED, t, "expected ')' in comptime type");
|
||||
vec_free(args);
|
||||
return 0;
|
||||
}
|
||||
@@ -949,7 +965,7 @@ static spl_ast_node_ref_t parse_type_comptime_call(parser_t *p) {
|
||||
static spl_ast_node_ref_t parse_type_expr(parser_t *p) {
|
||||
const spl_tok_t *t = peek(p);
|
||||
if (!t) {
|
||||
SPL_FATAL(t, "expected type");
|
||||
PARSE_FATAL(p, SPL_DIAG_KIND_PARSE_EXPECTED, t, "expected type");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -980,7 +996,7 @@ static spl_ast_node_ref_t parse_type_expr(parser_t *p) {
|
||||
|
||||
t = peek(p);
|
||||
if (!t || t->type != TOK_R_BRACKET) {
|
||||
SPL_FATAL(t, "expected ']' in array type");
|
||||
PARSE_FATAL(p, SPL_DIAG_KIND_PARSE_EXPECTED, t, "expected ']' in array type");
|
||||
return 0;
|
||||
}
|
||||
advance(p);
|
||||
@@ -1027,7 +1043,7 @@ static spl_ast_node_ref_t parse_type_expr(parser_t *p) {
|
||||
|
||||
t = peek(p);
|
||||
if (!t || t->type != TOK_R_PAREN) {
|
||||
SPL_FATAL(t, "expected ')' in parenthesized type");
|
||||
PARSE_FATAL(p, SPL_DIAG_KIND_PARSE_EXPECTED, t, "expected ')' in parenthesized type");
|
||||
return 0;
|
||||
}
|
||||
advance(p);
|
||||
@@ -1071,37 +1087,35 @@ static spl_ast_node_ref_vec_t parse_aggregate_fields(parser_t *p) {
|
||||
|
||||
const spl_tok_t *t = peek(p);
|
||||
if (!t || t->type != TOK_L_BRACE) {
|
||||
SPL_FATAL(t, "expected '{' in aggregate literal");
|
||||
return fields; // 空 vec,调用者处理
|
||||
PARSE_FATAL(p, SPL_DIAG_KIND_PARSE_EXPECTED, t, "expected '{' in aggregate literal");
|
||||
return fields;
|
||||
}
|
||||
advance(p); // 消费 '{'
|
||||
advance(p);
|
||||
|
||||
while (!p->failed) {
|
||||
t = peek(p);
|
||||
if (!t || t->type == TOK_R_BRACE || t->type == TOK_EOF)
|
||||
break;
|
||||
|
||||
// 字段必须由 '.' 开头
|
||||
if (t->type != TOK_DOT) {
|
||||
SPL_FATAL(t, "expected '.' in aggregate field initializer");
|
||||
PARSE_FATAL(p, SPL_DIAG_KIND_PARSE_EXPECTED, t,
|
||||
"expected '.' in aggregate field initializer");
|
||||
break;
|
||||
}
|
||||
advance(p);
|
||||
|
||||
t = peek(p);
|
||||
if (!t || t->type != TOK_IDENT) {
|
||||
SPL_FATAL(t, "expected field name after '.'");
|
||||
PARSE_FATAL(p, SPL_DIAG_KIND_PARSE_EXPECTED, t, "expected field name after '.'");
|
||||
break;
|
||||
}
|
||||
advance(p);
|
||||
|
||||
// 创建 struct_init_item 节点
|
||||
spl_ast_node_ref_t item_ref = new_node(p, SPL_AST_STRUCT_INIT_ITEM, t);
|
||||
spl_ast_node_t *item = node_at(p->ast, item_ref);
|
||||
SET_STR_FIELD(p->ast, item->struct_init_item.name, t);
|
||||
item->struct_init_item.expr = 0;
|
||||
|
||||
// 可选:= 表达式
|
||||
if (peek(p) && peek(p)->type == TOK_ASSIGN) {
|
||||
advance(p);
|
||||
spl_ast_node_ref_t expr_ref = parse_expr(p);
|
||||
@@ -1111,7 +1125,6 @@ static spl_ast_node_ref_vec_t parse_aggregate_fields(parser_t *p) {
|
||||
|
||||
vec_push(fields, item_ref);
|
||||
|
||||
// 分隔符
|
||||
t = peek(p);
|
||||
if (t && (t->type == TOK_COMMA || t->type == TOK_SEMICOLON)) {
|
||||
advance(p);
|
||||
@@ -1122,9 +1135,9 @@ static spl_ast_node_ref_vec_t parse_aggregate_fields(parser_t *p) {
|
||||
|
||||
t = peek(p);
|
||||
if (!t || t->type != TOK_R_BRACE) {
|
||||
SPL_FATAL(t, "expected '}' in aggregate literal");
|
||||
PARSE_FATAL(p, SPL_DIAG_KIND_PARSE_EXPECTED, t, "expected '}' in aggregate literal");
|
||||
} else {
|
||||
advance(p); // 消费 '}'
|
||||
advance(p);
|
||||
}
|
||||
|
||||
return fields;
|
||||
@@ -1295,7 +1308,7 @@ static spl_ast_node_ref_t parse_prefix(parser_t *p) {
|
||||
else if (kw && kw->type == KW_FOR)
|
||||
ref = parse_for_expr(p);
|
||||
else {
|
||||
SPL_FATAL(kw, "expected while/loop/for after label");
|
||||
PARSE_FATAL(p, SPL_DIAG_KIND_PARSE_EXPECTED, kw, "expected while/loop/for after label");
|
||||
return 0;
|
||||
}
|
||||
if (!ref)
|
||||
@@ -1357,7 +1370,7 @@ static spl_ast_node_ref_t parse_postfix(parser_t *p) {
|
||||
|
||||
t = peek(p);
|
||||
if (!t || t->type != TOK_R_PAREN) {
|
||||
SPL_FATAL(t, "expected ')' in call");
|
||||
PARSE_FATAL(p, SPL_DIAG_KIND_PARSE_EXPECTED, t, "expected ')' in call");
|
||||
return expr;
|
||||
}
|
||||
advance(p);
|
||||
@@ -1378,7 +1391,8 @@ static spl_ast_node_ref_t parse_postfix(parser_t *p) {
|
||||
spl_ast_node_ref_t ref = mk_unary(p, t, SPL_UNARY_OP_DEREF, expr);
|
||||
expr = ref;
|
||||
} else {
|
||||
SPL_FATAL(next, "expected identifier or '*' after '.'");
|
||||
PARSE_FATAL(p, SPL_DIAG_KIND_PARSE_EXPECTED, next,
|
||||
"expected identifier or '*' after '.'");
|
||||
break;
|
||||
}
|
||||
} else if (t->type == TOK_L_BRACKET) {
|
||||
@@ -1392,7 +1406,7 @@ static spl_ast_node_ref_t parse_postfix(parser_t *p) {
|
||||
end = parse_expr(p);
|
||||
t = peek(p);
|
||||
if (!t || t->type != TOK_R_BRACKET) {
|
||||
SPL_FATAL(t, "expected ']' in slice");
|
||||
PARSE_FATAL(p, SPL_DIAG_KIND_PARSE_EXPECTED, t, "expected ']' in slice");
|
||||
return expr;
|
||||
}
|
||||
advance(p);
|
||||
@@ -1404,7 +1418,7 @@ static spl_ast_node_ref_t parse_postfix(parser_t *p) {
|
||||
} else {
|
||||
t = peek(p);
|
||||
if (!t || t->type != TOK_R_BRACKET) {
|
||||
SPL_FATAL(t, "expected ']' in index");
|
||||
PARSE_FATAL(p, SPL_DIAG_KIND_PARSE_EXPECTED, t, "expected ']' in index");
|
||||
return expr;
|
||||
}
|
||||
advance(p);
|
||||
@@ -1423,7 +1437,7 @@ static spl_ast_node_ref_t parse_postfix(parser_t *p) {
|
||||
static spl_ast_node_ref_t parse_primary(parser_t *p) {
|
||||
const spl_tok_t *t = peek(p);
|
||||
if (!t) {
|
||||
SPL_FATAL(t, "unexpected end of expression");
|
||||
PARSE_FATAL(p, SPL_DIAG_KIND_PARSE_UNRECOGNIZED, t, "unexpected end of expression");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1491,7 +1505,7 @@ static spl_ast_node_ref_t parse_primary(parser_t *p) {
|
||||
advance(p);
|
||||
const spl_tok_t *nx = peek(p);
|
||||
if (!nx) {
|
||||
SPL_FATAL(t, "unexpected '.'");
|
||||
PARSE_FATAL(p, SPL_DIAG_KIND_PARSE_UNRECOGNIZED, t, "unexpected '.'");
|
||||
return 0;
|
||||
}
|
||||
if (nx->type == TOK_L_BRACE && !p->stop_agg) {
|
||||
@@ -1508,7 +1522,7 @@ static spl_ast_node_ref_t parse_primary(parser_t *p) {
|
||||
spl_ast_node_ref_vec_t elems = parse_expr_list(p);
|
||||
const spl_tok_t *close = peek(p);
|
||||
if (!close || close->type != TOK_R_BRACKET) {
|
||||
SPL_FATAL(close, "expected ']'");
|
||||
PARSE_FATAL(p, SPL_DIAG_KIND_PARSE_EXPECTED, close, "expected ']'");
|
||||
return 0;
|
||||
}
|
||||
advance(p); // 消费 ']'
|
||||
@@ -1518,7 +1532,7 @@ static spl_ast_node_ref_t parse_primary(parser_t *p) {
|
||||
arr->array_literal.elem_type = 0;
|
||||
return ref;
|
||||
} else {
|
||||
SPL_FATAL(nx, "expected '{' or '[' after '.'");
|
||||
PARSE_FATAL(p, SPL_DIAG_KIND_PARSE_EXPECTED, nx, "expected '{' or '[' after '.'");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -1552,7 +1566,7 @@ static spl_ast_node_ref_t parse_primary(parser_t *p) {
|
||||
}
|
||||
t = peek(p);
|
||||
if (!t || t->type != TOK_R_PAREN) {
|
||||
SPL_FATAL(t, "expected ')'");
|
||||
PARSE_FATAL(p, SPL_DIAG_KIND_PARSE_EXPECTED, t, "expected ')'");
|
||||
return 0;
|
||||
}
|
||||
advance(p);
|
||||
@@ -1562,7 +1576,7 @@ static spl_ast_node_ref_t parse_primary(parser_t *p) {
|
||||
} else {
|
||||
t = peek(p);
|
||||
if (!t || t->type != TOK_R_PAREN) {
|
||||
SPL_FATAL(t, "expected ')'");
|
||||
PARSE_FATAL(p, SPL_DIAG_KIND_PARSE_EXPECTED, t, "expected ')'");
|
||||
return 0;
|
||||
}
|
||||
advance(p);
|
||||
@@ -1581,7 +1595,7 @@ static spl_ast_node_ref_t parse_primary(parser_t *p) {
|
||||
case KW_MATCH:
|
||||
return parse_match_expr(p);
|
||||
default:
|
||||
SPL_FATAL(t, "unrecognized expression");
|
||||
PARSE_FATAL(p, SPL_DIAG_KIND_PARSE_UNRECOGNIZED, t, "unrecognized expression");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -1609,7 +1623,7 @@ static spl_ast_node_ref_t parse_array_literal(parser_t *p) {
|
||||
|
||||
t = peek(p);
|
||||
if (!t || t->type != TOK_R_BRACKET) {
|
||||
SPL_FATAL(t, "expected ']' in array literal");
|
||||
PARSE_FATAL(p, SPL_DIAG_KIND_PARSE_EXPECTED, t, "expected ']' in array literal");
|
||||
return 0;
|
||||
}
|
||||
advance(p);
|
||||
@@ -1618,7 +1632,7 @@ static spl_ast_node_ref_t parse_array_literal(parser_t *p) {
|
||||
|
||||
t = peek(p);
|
||||
if (!t || t->type != TOK_L_BRACKET) {
|
||||
SPL_FATAL(t, "expected '[' in array literal");
|
||||
PARSE_FATAL(p, SPL_DIAG_KIND_PARSE_EXPECTED, t, "expected '[' in array literal");
|
||||
return 0;
|
||||
}
|
||||
advance(p);
|
||||
@@ -1627,7 +1641,7 @@ static spl_ast_node_ref_t parse_array_literal(parser_t *p) {
|
||||
|
||||
t = peek(p);
|
||||
if (!t || t->type != TOK_R_BRACKET) {
|
||||
SPL_FATAL(t, "expected ']' in array literal");
|
||||
PARSE_FATAL(p, SPL_DIAG_KIND_PARSE_EXPECTED, t, "expected ']' in array literal");
|
||||
return 0;
|
||||
}
|
||||
advance(p);
|
||||
@@ -1650,7 +1664,7 @@ 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 name");
|
||||
PARSE_FATAL(p, SPL_DIAG_KIND_PARSE_EXPECTED, name, "expected comptime name");
|
||||
return 0;
|
||||
}
|
||||
advance(p);
|
||||
@@ -1666,7 +1680,7 @@ static spl_ast_node_ref_t parse_comptime_call(parser_t *p) {
|
||||
args = parse_expr_list(p);
|
||||
t = peek(p);
|
||||
if (!t || t->type != TOK_R_PAREN) {
|
||||
SPL_FATAL(t, "expected ')' in comptime call");
|
||||
PARSE_FATAL(p, SPL_DIAG_KIND_PARSE_EXPECTED, t, "expected ')' in comptime call");
|
||||
vec_free(args);
|
||||
return 0;
|
||||
}
|
||||
@@ -1688,7 +1702,7 @@ static spl_ast_node_ref_t parse_label(parser_t *p) {
|
||||
advance(p);
|
||||
const spl_tok_t *name = peek(p);
|
||||
if (!name || name->type != TOK_IDENT) {
|
||||
SPL_FATAL(name, "expected identifier after '$'");
|
||||
PARSE_FATAL(p, SPL_DIAG_KIND_PARSE_EXPECTED, name, "expected identifier after '$'");
|
||||
return 0;
|
||||
}
|
||||
advance(p);
|
||||
@@ -1726,14 +1740,15 @@ static spl_ast_node_ref_t parse_if_expr(parser_t *p) {
|
||||
advance(p);
|
||||
init_expr = parse_expr(p);
|
||||
} else {
|
||||
SPL_FATAL(t, "expected '=' in if var");
|
||||
PARSE_FATAL(p, SPL_DIAG_KIND_PARSE_EXPECTED, t, "expected '=' in if var");
|
||||
return 0;
|
||||
}
|
||||
} else if (t && t->type == TOK_ASSIGN) {
|
||||
advance(p);
|
||||
init_expr = parse_expr(p);
|
||||
} else {
|
||||
SPL_FATAL(t, "expected type annotation or '=' in if var");
|
||||
PARSE_FATAL(p, SPL_DIAG_KIND_PARSE_EXPECTED, t,
|
||||
"expected type annotation or '=' in if var");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1847,7 +1862,7 @@ static spl_ast_node_ref_t parse_for_expr(parser_t *p) {
|
||||
|
||||
const spl_tok_t *t = peek(p);
|
||||
if (!t || t->type != KW_AS) {
|
||||
SPL_FATAL(t, "expected 'as' in for loop");
|
||||
PARSE_FATAL(p, SPL_DIAG_KIND_PARSE_EXPECTED, t, "expected 'as' in for loop");
|
||||
return 0;
|
||||
}
|
||||
advance(p);
|
||||
@@ -1856,7 +1871,7 @@ static spl_ast_node_ref_t parse_for_expr(parser_t *p) {
|
||||
vec_init(idents);
|
||||
t = peek(p);
|
||||
if (!t || (t->type != TOK_IDENT && t->type != KW_UNDERSCORE)) {
|
||||
SPL_FATAL(t, "expected binding variable or '_' in for");
|
||||
PARSE_FATAL(p, SPL_DIAG_KIND_PARSE_EXPECTED, t, "expected binding variable or '_' in for");
|
||||
return 0;
|
||||
}
|
||||
advance(p);
|
||||
@@ -1868,7 +1883,8 @@ static spl_ast_node_ref_t parse_for_expr(parser_t *p) {
|
||||
advance(p);
|
||||
t = peek(p);
|
||||
if (!t || (t->type != TOK_IDENT && t->type != KW_UNDERSCORE)) {
|
||||
SPL_FATAL(t, "expected binding variable or '_' in for");
|
||||
PARSE_FATAL(p, SPL_DIAG_KIND_PARSE_EXPECTED, t,
|
||||
"expected binding variable or '_' in for");
|
||||
return 0;
|
||||
}
|
||||
advance(p);
|
||||
@@ -1919,7 +1935,7 @@ static int parse_match_arm(parser_t *p, spl_ast_node_ref_vec_t *patterns_out,
|
||||
|
||||
const spl_tok_t *t = peek(p);
|
||||
if (!t || t->type != TOK_RIGHT_FAT_ARROW) {
|
||||
SPL_FATAL(t, "expected '=>' in match arm");
|
||||
PARSE_FATAL(p, SPL_DIAG_KIND_PARSE_EXPECTED, t, "expected '=>' in match arm");
|
||||
return 0;
|
||||
}
|
||||
advance(p);
|
||||
@@ -1927,7 +1943,7 @@ static int parse_match_arm(parser_t *p, spl_ast_node_ref_vec_t *patterns_out,
|
||||
spl_ast_node_ref_t body;
|
||||
t = peek(p);
|
||||
if (!t || t->type != TOK_L_BRACE) {
|
||||
SPL_FATAL(t, "expected block after '=>' in match arm");
|
||||
PARSE_FATAL(p, SPL_DIAG_KIND_PARSE_EXPECTED, t, "expected block after '=>' in match arm");
|
||||
return 0;
|
||||
}
|
||||
body = parse_block(p);
|
||||
@@ -1952,7 +1968,7 @@ static spl_ast_node_ref_t parse_match_expr(parser_t *p) {
|
||||
|
||||
const spl_tok_t *t = peek(p);
|
||||
if (!t || t->type != TOK_L_BRACE) {
|
||||
SPL_FATAL(t, "expected '{' in match");
|
||||
PARSE_FATAL(p, SPL_DIAG_KIND_PARSE_EXPECTED, t, "expected '{' in match");
|
||||
return 0;
|
||||
}
|
||||
advance(p);
|
||||
@@ -1973,7 +1989,7 @@ static spl_ast_node_ref_t parse_match_expr(parser_t *p) {
|
||||
|
||||
t = peek(p);
|
||||
if (!t || t->type != TOK_R_BRACE) {
|
||||
SPL_FATAL(t, "expected '}' in match");
|
||||
PARSE_FATAL(p, SPL_DIAG_KIND_PARSE_EXPECTED, t, "expected '}' in match");
|
||||
return 0;
|
||||
}
|
||||
advance(p);
|
||||
@@ -2145,7 +2161,7 @@ static spl_ast_node_ref_t parse_statement(parser_t *p) {
|
||||
node_at(p->ast, ref)->statement_expr.expr = expr;
|
||||
return ref;
|
||||
} else {
|
||||
SPL_FATAL(t, "unrecognized statement");
|
||||
PARSE_FATAL(p, SPL_DIAG_KIND_PARSE_UNRECOGNIZED, t, "unrecognized statement");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -2155,7 +2171,7 @@ static spl_ast_node_ref_t parse_statement(parser_t *p) {
|
||||
static spl_ast_node_ref_t parse_block(parser_t *p) {
|
||||
const spl_tok_t *start = peek(p);
|
||||
if (!start || start->type != TOK_L_BRACE) {
|
||||
SPL_FATAL(start, "expected '{'");
|
||||
PARSE_FATAL(p, SPL_DIAG_KIND_PARSE_EXPECTED, start, "expected '{'");
|
||||
return 0;
|
||||
}
|
||||
advance(p);
|
||||
@@ -2168,7 +2184,7 @@ static spl_ast_node_ref_t parse_block(parser_t *p) {
|
||||
while (!p->failed) {
|
||||
const spl_tok_t *t = peek(p);
|
||||
if (!t || t->type == TOK_EOF) {
|
||||
SPL_FATAL(t, "block missing '}'");
|
||||
PARSE_FATAL(p, SPL_DIAG_KIND_PARSE_EXPECTED, t, "block missing '}'");
|
||||
return ref;
|
||||
}
|
||||
if (t->type == TOK_R_BRACE) {
|
||||
@@ -2190,7 +2206,8 @@ static spl_ast_node_ref_t parse_block(parser_t *p) {
|
||||
vec_push(block->block.stmts, expr);
|
||||
} else if (t && t->type == TOK_R_BRACE) {
|
||||
if (block->block.tail_expr != 0) {
|
||||
SPL_FATAL(t, "only one tail expression allowed");
|
||||
PARSE_FATAL(p, SPL_DIAG_KIND_PARSE_UNRECOGNIZED, t,
|
||||
"only one tail expression allowed");
|
||||
}
|
||||
block->block.tail_expr = expr;
|
||||
} else {
|
||||
@@ -2202,12 +2219,13 @@ static spl_ast_node_ref_t parse_block(parser_t *p) {
|
||||
if (block_like) {
|
||||
vec_push(block->block.stmts, expr);
|
||||
} else {
|
||||
SPL_FATAL(t, "expected ';' or '}' after expression");
|
||||
PARSE_FATAL(p, SPL_DIAG_KIND_PARSE_EXPECTED, t,
|
||||
"expected ';' or '}' after expression");
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
SPL_FATAL(t, "unrecognized token in block");
|
||||
PARSE_FATAL(p, SPL_DIAG_KIND_PARSE_UNRECOGNIZED, t, "unrecognized token in block");
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -2220,7 +2238,7 @@ void spl_ast_init(spl_ast_t *ast, const spl_tok_vec_t *tok_vec) {
|
||||
vec_init(ast->node_buckets);
|
||||
vec_init(ast->str_buckets);
|
||||
ast->root = 0;
|
||||
ast->parsed = 0;
|
||||
ast->diag = NULL;
|
||||
|
||||
spl_ast_node_t n = {0};
|
||||
vec_push(ast->node_buckets, n);
|
||||
@@ -2232,11 +2250,11 @@ void spl_ast_parse(spl_ast_t *ast) {
|
||||
|
||||
parser_t p;
|
||||
p.ast = ast;
|
||||
p.diag = ast->diag;
|
||||
p.pos = 0;
|
||||
p.failed = 0;
|
||||
p.stop_as = 0;
|
||||
p.stop_agg = 0;
|
||||
ast->parsed = 0;
|
||||
|
||||
spl_ast_node_ref_vec_t external_tags;
|
||||
vec_init(external_tags);
|
||||
@@ -2276,7 +2294,6 @@ void spl_ast_parse(spl_ast_t *ast) {
|
||||
node_at(ast, root)->root.members = container_members;
|
||||
|
||||
ast->root = root;
|
||||
ast->parsed = p.failed ? -1 : 1;
|
||||
}
|
||||
|
||||
void spl_ast_drop(spl_ast_t *ast) {
|
||||
@@ -2287,7 +2304,6 @@ void spl_ast_drop(spl_ast_t *ast) {
|
||||
vec_for(ast->node_buckets, idx) { vec_free(vec_at(ast->node_buckets, idx).attrs); }
|
||||
vec_free(ast->node_buckets);
|
||||
vec_free(ast->input);
|
||||
ast->parsed = 0;
|
||||
ast->root = 0;
|
||||
}
|
||||
|
||||
@@ -2297,16 +2313,6 @@ spl_ast_node_t *spl_ast_node(spl_ast_t *ast, spl_ast_node_ref_t node) {
|
||||
return &ast->node_buckets.data[node];
|
||||
}
|
||||
|
||||
void spl_ast_valid(spl_ast_t *ast) {
|
||||
if (!ast)
|
||||
return;
|
||||
if (ast->parsed != 1) {
|
||||
printf("valid: AST not parsed successfully (parsed=%d)\n", ast->parsed);
|
||||
return;
|
||||
}
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
typedef VEC(char) dump_stack_t;
|
||||
|
||||
static void dump_node(spl_ast_t *ast, spl_ast_node_ref_t node_ref, dump_stack_t *stack, bool last);
|
||||
@@ -2527,7 +2533,6 @@ static void dump_node(spl_ast_t *ast, spl_ast_node_ref_t node_ref, dump_stack_t
|
||||
break;
|
||||
|
||||
case SPL_AST_EXPR_AGGREGATE_LIT:
|
||||
|
||||
dump_vec(ast, node->aggregate_literal.fields, stack);
|
||||
break;
|
||||
|
||||
|
||||
Reference in new issue
Block a user