stage1 重写进行代码设计并重构 提供diag替换老旧错误处理

This commit is contained in:
zzy committed 2026-09-16 15:21:59 +08:00
1 parent 7cbe2d2b9a
commit e4347cc3ea
14 files changed
+983 -526

No files matched your search

+104 -99
View File
@@ -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, &params);
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;