stage2 修复全局变量未完成的问题 提供错误处理解析

This commit is contained in:
zzy committed 2026-09-25 13:46:07 +08:00
1 parent c0a86ea552
commit 0b8f649818
11 files changed
+317 -18

No files matched your search

+38 -1
View File
@@ -282,6 +282,7 @@ fn can_start_expr(kind: TokenKind): bool {
.For => { ret true; },
.Match => { ret true; },
.Comptime => { ret true; },
.Try => { ret true; },
_ => { ret false; },
}
},
@@ -321,6 +322,7 @@ fn can_start_statement(kind: TokenKind): bool {
.Break => { ret true; },
.Continue => { ret true; },
.Defer => { ret true; },
.Errdefer => { ret true; },
.Var => { ret true; },
.Const => { ret true; },
.Type => { ret true; },
@@ -1237,7 +1239,19 @@ fn parse_expr_prec(self: *Parser, min_prec: i32): usize {
}
fn parse_expr(self: *Parser): usize {
ret parse_expr_prec(self, 1);
var e = parse_expr_prec(self, 1);
// `expr catch <pattern> <block>`:catch 用解包语法绑定错误。
while !self.failed {
var t = peek(self);
if t == null { break; }
if !kind_is_keyword(t.kind, .Catch) { break; }
advance(self);
var pat = parse_pattern(self);
if pat == 0 { ret e; }
var handler = parse_block(self);
e = new_node(self, .ExprCatch(.{ .value = e, .pattern = pat, .handler = handler }), t);
}
ret e;
}
fn parse_cast(self: *Parser): usize {
@@ -1444,6 +1458,12 @@ fn parse_primary(self: *Parser): usize {
if @enum2int(k) == @enum2int(Keyword.Loop) { ret parse_loop_expr(self); }
if @enum2int(k) == @enum2int(Keyword.For) { ret parse_for_expr(self); }
if @enum2int(k) == @enum2int(Keyword.Match) { ret parse_match_expr(self); }
// `try <expr>`:错误上抛前缀。
if @enum2int(k) == @enum2int(Keyword.Try) {
advance(self);
var tv = parse_expr(self);
ret new_node(self, .ExprTry(.{ .value = tv }), t);
}
// `comptime <expr>`:编译期表达式(可调用普通函数、返回类型等)。
if @enum2int(k) == @enum2int(Keyword.Comptime) {
advance(self);
@@ -1958,6 +1978,22 @@ fn parse_defer_stmt(self: *Parser): usize {
ret new_node(self, .StatementDefer(.{ .body = body }), kw);
}
fn parse_errdefer_stmt(self: *Parser): usize {
var kw = peek(self);
if kw == null || !kind_is_keyword(kw.kind, .Errdefer) { ret 0; }
advance(self);
var body: usize = 0;
var t = peek(self);
if t != null && kind_is_punct(t.kind, .LBrace) { body = parse_block(self); }
else if t != null && can_start_statement(t.kind) { body = parse_statement(self); }
else {
body = parse_expr(self);
t = peek(self);
if t != null && kind_is_punct(t.kind, .Semicolon) { advance(self); }
}
ret new_node(self, .StatementErrdefer(.{ .body = body }), kw);
}
fn parse_comptime_stmt(self: *Parser): usize {
var kw = peek(self);
if kw == null || !kind_is_keyword(kw.kind, .Comptime) { ret 0; }
@@ -1979,6 +2015,7 @@ fn parse_statement(self: *Parser): usize {
if @enum2int(k) == @enum2int(Keyword.Break) { ret parse_break_stmt(self); }
if @enum2int(k) == @enum2int(Keyword.Continue) { ret parse_continue_stmt(self); }
if @enum2int(k) == @enum2int(Keyword.Defer) { ret parse_defer_stmt(self); }
if @enum2int(k) == @enum2int(Keyword.Errdefer) { ret parse_errdefer_stmt(self); }
if @enum2int(k) == @enum2int(Keyword.Comptime) { ret parse_comptime_stmt(self); }
if @enum2int(k) == @enum2int(Keyword.Var) ||
@enum2int(k) == @enum2int(Keyword.Const) ||