feat: let mut + 赋值语句 — while 循环可修改变量
- lexer: 新增 TOK_MUT 关键字 - ast: AST_ASSIGN_STMT 节点 + let_stmt.is_mut 标志 - parser: ‘let mut’ 前缀识别 + ‘ident = expr;’ 赋值语句 - sema: Symbol.is_mut 可变性检查(不可变变量赋值报错) - codegen: AST_ASSIGN_STMT → store 指令 - 新增集成测试 06_mut_while.l(while 循环 + 计数器) 基于 Codex 分析报告 P0 建议。
This commit is contained in:
+15
-1
@@ -194,6 +194,8 @@ static AstNode* parse_statement(Parser* p, ErrorInfo* error) {
|
||||
|
||||
if (t->kind == TOK_LET) {
|
||||
advance(p);
|
||||
bool is_mut = false;
|
||||
if (peek(p)->kind == TOK_MUT) { is_mut = true; advance(p); }
|
||||
const Token* name = expect(p, TOK_IDENT, error, "let 后应为变量名");
|
||||
if (!name) return NULL;
|
||||
// 可选的类型标注
|
||||
@@ -214,7 +216,7 @@ static AstNode* parse_statement(Parser* p, ErrorInfo* error) {
|
||||
if (!expect(p, TOK_SEMICOLON, error, "缺少 ';'")) return NULL;
|
||||
return ast_make_let(p->arena,
|
||||
arena_strdup_impl(p->arena, name->start, name->length),
|
||||
annot_type, has_type_annot, init, t->line, t->col);
|
||||
annot_type, has_type_annot, is_mut, init, t->line, t->col);
|
||||
}
|
||||
|
||||
if (t->kind == TOK_IF) {
|
||||
@@ -255,6 +257,18 @@ static AstNode* parse_statement(Parser* p, ErrorInfo* error) {
|
||||
return ast_make_return(p->arena, expr, t->line, t->col);
|
||||
}
|
||||
|
||||
// 赋值语句: ident = expr ;
|
||||
if (t->kind == TOK_IDENT && (t + 1)->kind == TOK_ASSIGN) {
|
||||
const Token* name = advance(p); // 消费标识符
|
||||
advance(p); // 消费 '='
|
||||
AstNode* value = parse_expr(p, error);
|
||||
if (!value) return NULL;
|
||||
if (!expect(p, TOK_SEMICOLON, error, "缺少 ';'")) return NULL;
|
||||
return ast_make_assign(p->arena,
|
||||
arena_strdup_impl(p->arena, name->start, name->length),
|
||||
value, name->line, name->col);
|
||||
}
|
||||
|
||||
// 表达式语句
|
||||
AstNode* expr = parse_expr(p, error);
|
||||
if (!expr) return NULL;
|
||||
|
||||
Reference in New Issue
Block a user