feat: try-catch-finally 异常处理

语法: try { ... } catch (e) { ... } finally { ... }
catch 和 finally 都是可选的,但至少需要一个。throw expr 抛出任意值。

- Lexer: 新增 try, catch, finally, throw 关键字
- AST: Stmt::Try { body, catch_var, catch_body, finally_body } + Stmt::Throw(Expr)
- Parser: try/catch/finally/throw 语句解析,更新 synchronize()
- Opcode: Throw = 46,FunctionProto 新增 exception_handlers 表
- ExceptionHandler: { try_start, try_end, catch_ip, catch_slot, finally_ip }
- Compiler: compile_try 将 finally 在成功/异常两条路径各内联一次
- VM: unwind() 栈展开 + find_handler() 处理器搜索
- RuntimeError(除零、未定义变量等)在 try 块内自动转为可捕获异常
- LSP: 补全关键字列表追加

已知限制: return/break/continue 在 try-finally 内部不会先执行 finally

16 个新测试,全部 343 个测试通过。

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
0264408
2026-06-26 14:37:38 +08:00
parent deab894864
commit a70e5fbc30
11 changed files with 595 additions and 38 deletions
+4
View File
@@ -360,6 +360,10 @@ impl Lexer {
"true" => TokenKind::True,
"false" => TokenKind::False,
"nil" => TokenKind::Nil,
"try" => TokenKind::Try,
"catch" => TokenKind::Catch,
"finally" => TokenKind::Finally,
"throw" => TokenKind::Throw,
_ => TokenKind::Identifier(s),
};