feat: defer 延迟执行 — defer { stmts; } 在 return 前按 LIFO 执行

Token(73): +TOK_DEFER, AST(28): +AST_DEFER_STMT, 新增 38_defer.l
parser: defer { ... } 块 + defer expr; 表达式两种形式
codegen: defer 栈压入 block, emit_deferred() 在 return 前 LIFO 发射

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-06-07 13:51:10 +08:00
parent e60021b684
commit 0088347576
10 changed files with 62 additions and 6 deletions
+4
View File
@@ -15,6 +15,7 @@ typedef enum {
AST_WHILE_STMT,
AST_RETURN_STMT,
AST_EXPR_STMT,
AST_DEFER_STMT,
AST_BINARY_EXPR,
AST_UNARY_EXPR,
AST_CALL_EXPR,
@@ -88,6 +89,8 @@ struct AstNode {
struct { struct AstNode* expr; } return_stmt;
// AST_EXPR_STMT
struct { struct AstNode* expr; } expr_stmt;
// AST_DEFER_STMT
struct { struct AstNode* body; } defer_stmt;
// AST_BINARY_EXPR
struct { BinaryOp op; struct AstNode* left; struct AstNode* right; } binary;
// AST_UNARY_EXPR
@@ -153,6 +156,7 @@ AstNode* ast_make_if(void* alloc, AstNode* cond, AstNode* then_b, AstNode* else_
AstNode* ast_make_while(void* alloc, AstNode* cond, AstNode* body, SourceLoc loc);
AstNode* ast_make_return(void* alloc, AstNode* expr, SourceLoc loc);
AstNode* ast_make_expr_stmt(void* alloc, AstNode* expr, SourceLoc loc);
AstNode* ast_make_defer_stmt(void* alloc, AstNode* expr, SourceLoc loc);
AstNode* ast_make_binary(void* alloc, BinaryOp op, AstNode* left, AstNode* right, SourceLoc loc);
AstNode* ast_make_unary(void* alloc, BinaryOp op, AstNode* operand, SourceLoc loc);
AstNode* ast_make_call(void* alloc, const char* name, AstNode** args, const char** arg_names, size_t count, SourceLoc loc);