feat: for..in 范围语法 .. 改为 to 关键字
This commit is contained in:
@@ -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`
|
||||||
|
|
||||||
|
|||||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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,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,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;
|
||||||
|
|||||||
Reference in New Issue
Block a user