feat: for..in 范围语法 .. 改为 to 关键字

This commit is contained in:
2026-06-05 19:44:26 +08:00
parent 9a256d9be1
commit a28d33854c
8 changed files with 12 additions and 12 deletions
+1 -1
View File
@@ -98,7 +98,7 @@ graph TB
- `if` / `else` / `else if` - `if` / `else` / `else if`
- `while` 循环 - `while` 循环
- `for i in 0..10` (去糖为 while) - `for i in 0 to 10` (去糖为 while)
- `match expr { pat => { ... } _ => { ... } }` (去糖为 if-else) - `match expr { pat => { ... } _ => { ... } }` (去糖为 if-else)
- `return` - `return`
+3 -3
View File
@@ -188,13 +188,13 @@ while i < 5 {
### for 循环 ### for 循环
```rust ```rust
for i in 0..5 { for i in 0 to 5 {
print_i64(i); print_i64(i);
} }
// 输出: 0 1 2 3 4 // 输出: 0 1 2 3 4
``` ```
`for i in start..end` 等价于 `let mut i = start; while i < end { ...; i += 1; }` `for i in start to end` 等价于 `let mut i = start; while i < end { ...; i += 1; }`
### match ### match
@@ -566,7 +566,7 @@ l_lang.exe source.l --emit-ir
类型: i64 f64 bool str void struct enum [T;N] 类型: i64 f64 bool str void struct enum [T;N]
声明: let x = val let mut x = val 声明: let x = val let mut x = val
let x: Type = val type Alias = Type let x: Type = val type Alias = Type
控制流: if/else while for i in 0..N match 控制流: if/else while for i in 0 to N match
函数: fn name(p: T) -> Ret { return expr; } 函数: fn name(p: T) -> Ret { return expr; }
结构体: struct Name { f: Type } Name { f: val } 结构体: struct Name { f: Type } Name { f: val }
枚举: enum Name { A, B, C } Name::B 枚举: enum Name { A, B, C } Name::B
+1 -1
View File
@@ -58,6 +58,7 @@ static TokenKind check_keyword(const Token* tok) {
KW("mut", TOK_MUT); KW("mut", TOK_MUT);
KW("if", TOK_IF); KW("else", TOK_ELSE); KW("if", TOK_IF); KW("else", TOK_ELSE);
KW("while", TOK_WHILE); KW("for", TOK_FOR); KW("in", TOK_IN); KW("while", TOK_WHILE); KW("for", TOK_FOR); KW("in", TOK_IN);
KW("to", TOK_TO);
KW("return", TOK_RETURN); KW("return", TOK_RETURN);
KW("i64", TOK_I64); KW("f64", TOK_F64); KW("i64", TOK_I64); KW("f64", TOK_F64);
KW("bool", TOK_BOOL); KW("str", TOK_STR); KW("bool", TOK_BOOL); KW("str", TOK_STR);
@@ -137,7 +138,6 @@ Token* lex(Arena* a, const char* source, const char* filename,
else if (c == '>') { tokens[idx++] = make_token(&l, TOK_GT, l.pos, 1); advance(&l); } else if (c == '>') { tokens[idx++] = make_token(&l, TOK_GT, l.pos, 1); advance(&l); }
else if (c == '&' && peek_next(&l) == '&') { tokens[idx++] = make_token(&l, TOK_AND_AND, l.pos, 2); advance(&l); advance(&l); } else if (c == '&' && peek_next(&l) == '&') { tokens[idx++] = make_token(&l, TOK_AND_AND, l.pos, 2); advance(&l); advance(&l); }
else if (c == '|' && peek_next(&l) == '|') { tokens[idx++] = make_token(&l, TOK_PIPE_PIPE, l.pos, 2); advance(&l); advance(&l); } else if (c == '|' && peek_next(&l) == '|') { tokens[idx++] = make_token(&l, TOK_PIPE_PIPE, l.pos, 2); advance(&l); advance(&l); }
else if (c == '.' && peek_next(&l) == '.') { tokens[idx++] = make_token(&l, TOK_DOT_DOT, l.pos, 2); advance(&l); advance(&l); }
else if (c == '.') { tokens[idx++] = make_token(&l, TOK_DOT, l.pos, 1); advance(&l); } else if (c == '.') { tokens[idx++] = make_token(&l, TOK_DOT, l.pos, 1); advance(&l); }
else if (c == '[') { tokens[idx++] = make_token(&l, TOK_LBRACKET, l.pos, 1); advance(&l); } else if (c == '[') { tokens[idx++] = make_token(&l, TOK_LBRACKET, l.pos, 1); advance(&l); }
else if (c == ']') { tokens[idx++] = make_token(&l, TOK_RBRACKET, l.pos, 1); advance(&l); } else if (c == ']') { tokens[idx++] = make_token(&l, TOK_RBRACKET, l.pos, 1); advance(&l); }
+1 -1
View File
@@ -18,7 +18,7 @@ static const char* NAMES[] = {
[TOK_EQ_EQ] = "==", [TOK_BANG_EQ] = "!=", [TOK_EQ_EQ] = "==", [TOK_BANG_EQ] = "!=",
[TOK_LT] = "<", [TOK_GT] = ">", [TOK_LT_EQ] = "<=", [TOK_GT_EQ] = ">=", [TOK_LT] = "<", [TOK_GT] = ">", [TOK_LT_EQ] = "<=", [TOK_GT_EQ] = ">=",
[TOK_AND_AND] = "&&", [TOK_PIPE_PIPE] = "||", [TOK_BANG] = "!", [TOK_AND_AND] = "&&", [TOK_PIPE_PIPE] = "||", [TOK_BANG] = "!",
[TOK_ARROW] = "->", [TOK_DOT_DOT] = "..", [TOK_MATCH_ARROW] = "=>", [TOK_ARROW] = "->", [TOK_TO] = "to", [TOK_MATCH_ARROW] = "=>",
[TOK_PLUS_EQ] = "+=", [TOK_MINUS_EQ] = "-=", [TOK_STAR_EQ] = "*=", [TOK_SLASH_EQ] = "/=", [TOK_PLUS_EQ] = "+=", [TOK_MINUS_EQ] = "-=", [TOK_STAR_EQ] = "*=", [TOK_SLASH_EQ] = "/=",
[TOK_LPAREN] = "(", [TOK_RPAREN] = ")", [TOK_LPAREN] = "(", [TOK_RPAREN] = ")",
[TOK_LBRACE] = "{", [TOK_RBRACE] = "}", [TOK_LBRACE] = "{", [TOK_RBRACE] = "}",
+1 -1
View File
@@ -18,7 +18,7 @@ typedef enum {
TOK_PLUS, TOK_MINUS, TOK_STAR, TOK_SLASH, TOK_PERCENT, TOK_PLUS, TOK_MINUS, TOK_STAR, TOK_SLASH, TOK_PERCENT,
TOK_EQ_EQ, TOK_BANG_EQ, TOK_LT, TOK_GT, TOK_LT_EQ, TOK_GT_EQ, TOK_EQ_EQ, TOK_BANG_EQ, TOK_LT, TOK_GT, TOK_LT_EQ, TOK_GT_EQ,
TOK_AND_AND, TOK_PIPE_PIPE, TOK_BANG, TOK_AND_AND, TOK_PIPE_PIPE, TOK_BANG,
TOK_ARROW, TOK_DOT_DOT, TOK_MATCH_ARROW, TOK_ARROW, TOK_TO, TOK_MATCH_ARROW,
TOK_PLUS_EQ, TOK_MINUS_EQ, TOK_STAR_EQ, TOK_SLASH_EQ, TOK_PLUS_EQ, TOK_MINUS_EQ, TOK_STAR_EQ, TOK_SLASH_EQ,
// 分隔符 // 分隔符
TOK_LPAREN, TOK_RPAREN, TOK_LBRACE, TOK_RBRACE, TOK_LPAREN, TOK_RPAREN, TOK_LBRACE, TOK_RBRACE,
+3 -3
View File
@@ -546,8 +546,8 @@ static AstNode* parse_statement(Parser* p, ErrorInfo* error) {
AstNode* start_expr = parse_expr(p, error); AstNode* start_expr = parse_expr(p, error);
if (!start_expr) return NULL; if (!start_expr) return NULL;
// 解析 '..' // 解析 'to'
if (!expect(p, TOK_DOT_DOT, error, "缺少 '..'")) return NULL; if (!expect(p, TOK_TO, error, "缺少 'to'")) return NULL;
// 解析结束表达式 // 解析结束表达式
AstNode* end_expr = parse_expr(p, error); AstNode* end_expr = parse_expr(p, error);
@@ -557,7 +557,7 @@ static AstNode* parse_statement(Parser* p, ErrorInfo* error) {
AstNode* body = parse_block(p, error); AstNode* body = parse_block(p, error);
if (!body) return NULL; if (!body) return NULL;
// 脱糖: for i in start..end { body; } // 脱糖: for i in start to end { body; }
// → { let mut i = start; while i < end { body; i = i + 1; } } // → { let mut i = start; while i < end { body; i = i + 1; } }
const char* vname = arena_strdup_impl(p->arena, var_name->start, var_name->length); const char* vname = arena_strdup_impl(p->arena, var_name->start, var_name->length);
+1 -1
View File
@@ -1,5 +1,5 @@
fn main() -> i64 { fn main() -> i64 {
for i in 0..5 { for i in 0 to 5 {
print_i64(i); print_i64(i);
} }
return 0; return 0;
+1 -1
View File
@@ -1,7 +1,7 @@
fn main() -> i64 { fn main() -> i64 {
let start: i64 = 10; let start: i64 = 10;
let end: i64 = 15; let end: i64 = 15;
for n in start..end { for n in start to end {
print_i64(n); print_i64(n);
} }
return 0; return 0;