feat: let mut 改为 var 关键字声明可变变量

This commit is contained in:
2026-06-05 19:47:00 +08:00
parent a28d33854c
commit ab4cc9a28b
10 changed files with 27 additions and 28 deletions
+1 -1
View File
@@ -55,7 +55,7 @@ static Token lex_number(Lexer* l) {
static TokenKind check_keyword(const Token* tok) {
#define KW(s, k) if (tok->length == sizeof(s)-1 && memcmp(tok->start, s, sizeof(s)-1) == 0) return k
KW("fn", TOK_FN); KW("let", TOK_LET);
KW("mut", TOK_MUT);
KW("var", TOK_VAR);
KW("if", TOK_IF); KW("else", TOK_ELSE);
KW("while", TOK_WHILE); KW("for", TOK_FOR); KW("in", TOK_IN);
KW("to", TOK_TO);
+1 -1
View File
@@ -5,7 +5,7 @@
#include <inttypes.h>
static const char* NAMES[] = {
[TOK_FN] = "fn", [TOK_LET] = "let", [TOK_MUT] = "mut", [TOK_IF] = "if",
[TOK_FN] = "fn", [TOK_LET] = "let", [TOK_VAR] = "var", [TOK_IF] = "if",
[TOK_ELSE] = "else", [TOK_WHILE] = "while", [TOK_FOR] = "for", [TOK_IN] = "in", [TOK_RETURN] = "return",
[TOK_STRUCT] = "struct", [TOK_TYPE] = "type", [TOK_ENUM] = "enum", [TOK_IMPL] = "impl",
[TOK_MATCH] = "match",
+1 -1
View File
@@ -6,7 +6,7 @@
// === Token 类型枚举 ===
typedef enum {
// 关键字
TOK_FN, TOK_LET, TOK_MUT, TOK_IF, TOK_ELSE, TOK_WHILE, TOK_FOR, TOK_IN, TOK_RETURN,
TOK_FN, TOK_LET, TOK_VAR, TOK_IF, TOK_ELSE, TOK_WHILE, TOK_FOR, TOK_IN, TOK_RETURN,
TOK_STRUCT, TOK_TYPE, TOK_ENUM, TOK_IMPL, TOK_MATCH,
// 类型关键字
TOK_I64, TOK_F64, TOK_BOOL, TOK_STR, TOK_VOID,
+7 -8
View File
@@ -472,11 +472,10 @@ static AstNode* parse_block(Parser* p, ErrorInfo* error) {
static AstNode* parse_statement(Parser* p, ErrorInfo* error) {
const Token* t = peek(p);
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 (t->kind == TOK_LET || t->kind == TOK_VAR) {
bool is_mut = (advance(p)->kind == TOK_VAR);
const Token* name = expect(p, TOK_IDENT, error,
is_mut ? "var 后应为变量名" : "let 后应为变量名");
if (!name) return NULL;
// 可选的类型标注
TypeKind annot_type = TYPE_UNKNOWN;
@@ -558,11 +557,11 @@ static AstNode* parse_statement(Parser* p, ErrorInfo* error) {
if (!body) return NULL;
// 脱糖: for i in start to end { body; }
// → { let mut i = start; while i < end { body; i = i + 1; } }
// → { var i = start; while i < end { body; i = i + 1; } }
const char* vname = arena_strdup_impl(p->arena, var_name->start, var_name->length);
// 构建: let mut i = start;
// 构建: var i = start;
AstNode* let_stmt = ast_make_let(p->arena, vname, TYPE_UNKNOWN, false, true, start_expr, NULL, 0, NULL, 0, tok_loc(var_name));
// 构建: i < end (while 条件)
@@ -589,7 +588,7 @@ static AstNode* parse_statement(Parser* p, ErrorInfo* error) {
// 构建: while i < end { ... body ... ; i = i + 1; }
AstNode* while_loop = ast_make_while(p->arena, cond, new_body, tok_loc(t));
// 包装: { let mut i = start; while i < end { ... } }
// 包装: { var i = start; while i < end { ... } }
AstNode* stmts_arr[2] = { let_stmt, while_loop };
AstNode** stmts = arena_alloc_impl(p->arena, 2 * sizeof(AstNode*));
memcpy(stmts, stmts_arr, 2 * sizeof(AstNode*));
+1 -1
View File
@@ -683,7 +683,7 @@ static void analyze_node(AstNode* node, Scope* scope, ErrorList* errors, Arena*
}
if (!sym->is_mut) {
error_add(errors, "<sema>", node->loc.line, node->loc.col,
"不能对不可变变量 '%s' 赋值(需用 let mut 声明)",
"不能对不可变变量 '%s' 赋值(需用 var 声明)",
node->as.assign_stmt.name);
node->type.kind = TYPE_ERROR;
break;