diff --git a/README.md b/README.md index 305eebd..5c4ca3a 100644 --- a/README.md +++ b/README.md @@ -87,7 +87,7 @@ graph TB | 字符串 | `str` | `"hello"` | | 结构体 | `struct` | `Point { x: i64, y: i64 }` | | 枚举 | `enum` | `Color { Red, Green, Blue }` | -| 数组 | `[T; N]` | `[i64; 10]` | +| 数组 | `T[N]` | `i64[10]` | | 无返回值 | `void` | 函数默认 | | 类型别名 | `type` | `type Meters = i64;` | diff --git a/docs/language-reference.md b/docs/language-reference.md index 90c8814..87784b9 100644 --- a/docs/language-reference.md +++ b/docs/language-reference.md @@ -350,10 +350,10 @@ let is_red = (c == Color::Red); // false ### 声明类型 ```rust -let arr: [i64; 5] = arr; // 声明未初始化的 5 个 i64 数组 +let arr: i64[5] = arr; // 声明未初始化的 5 个 i64 数组 ``` -数组类型语法: `[元素类型; 大小]` +数组类型语法: `元素类型[大小]`(后置维度) - `= arr` 是固定写法,表示声明未初始化的数组(`arr` 是变量名自身) - 大小必须是整数常量 @@ -373,7 +373,7 @@ print_i64(arr[1]); // 200 ### 循环遍历 ```rust -var arr: [i64; 5] = arr; +var arr: i64[5] = arr; var i: i64 = 0; while i < 5 { arr[i] = i * 10; @@ -499,7 +499,7 @@ fn main() -> i64 { ```rust fn main() -> i64 { - var arr: [i64; 5] = arr; + var arr: i64[5] = arr; // 填充数组 var i: i64 = 0; @@ -563,7 +563,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 var x = val let x: Type = val type Alias = Type 控制流: if/else while for i in 0 to N match diff --git a/src/parser/parser.c b/src/parser/parser.c index 40fe190..00b84f3 100644 --- a/src/parser/parser.c +++ b/src/parser/parser.c @@ -282,32 +282,12 @@ static TypeKind token_to_type(TokenKind k) { } // === 类型表达式解析(内置类型/结构体名/数组类型)=== +// 数组支持后置语法: T[N], T[N][M] 等 static TypeInfo parse_type_expr(Parser* p, ErrorInfo* error) { const Token* t = peek(p); - - // 数组类型: [element_type; size] - if (t->kind == TOK_LBRACKET) { - advance(p); // 跳过 '[' - TypeInfo elem = parse_type_expr(p, error); - if (elem.kind == TYPE_ERROR) return elem; - if (!expect(p, TOK_SEMICOLON, error, "数组类型中缺少 ';'")) { - TypeInfo ti = {0}; ti.kind = TYPE_ERROR; return ti; - } - const Token* size_tok = expect(p, TOK_INT_LIT, error, "数组大小必须是整数常量"); - if (!size_tok) { TypeInfo ti = {0}; ti.kind = TYPE_ERROR; return ti; } - int64_t size = tok_int_value(size_tok); - if (!expect(p, TOK_RBRACKET, error, "缺少 ']'")) { - TypeInfo ti = {0}; ti.kind = TYPE_ERROR; return ti; - } - TypeInfo ti = {0}; - ti.kind = TYPE_ARRAY; - ti.element_type = elem.kind; - ti.element_struct_name = elem.struct_name; - ti.array_size = size; - return ti; - } - TypeInfo ti = {0}; + + // 解析基础类型 if (tok_is_type(t->kind)) { advance(p); ti.kind = token_to_type(t->kind); @@ -319,7 +299,26 @@ static TypeInfo parse_type_expr(Parser* p, ErrorInfo* error) { error->message = "无效的类型"; error->filename = p->filename; error->line = t->line; error->col = t->col; ti.kind = TYPE_ERROR; + return ti; } + + // 后置数组维度: Type[N] → TYPE_ARRAY + if (peek(p)->kind == TOK_LBRACKET) { + advance(p); // 跳过 '[' + const Token* size_tok = expect(p, TOK_INT_LIT, error, "数组大小必须是整数常量"); + if (!size_tok) { ti.kind = TYPE_ERROR; return ti; } + int64_t size = tok_int_value(size_tok); + if (!expect(p, TOK_RBRACKET, error, "缺少 ']'")) { + ti.kind = TYPE_ERROR; return ti; + } + TypeInfo arr_ti = {0}; + arr_ti.kind = TYPE_ARRAY; + arr_ti.element_type = ti.kind; + arr_ti.element_struct_name = ti.struct_name; + arr_ti.array_size = size; + return arr_ti; + } + return ti; } diff --git a/test/programs/18_array.l b/test/programs/18_array.l index 4a9d2f3..1259786 100644 --- a/test/programs/18_array.l +++ b/test/programs/18_array.l @@ -1,5 +1,5 @@ fn main() -> i64 { - let arr: [i64; 3] = arr; + let arr: i64[3] = arr; arr[0] = 10; arr[1] = 20; arr[2] = 30; diff --git a/test/programs/24_array_struct.l b/test/programs/24_array_struct.l index 39a402c..b0a7c40 100644 --- a/test/programs/24_array_struct.l +++ b/test/programs/24_array_struct.l @@ -1,7 +1,7 @@ struct Point { x: i64, y: i64 } fn main() -> i64 { - let arr: [Point; 2] = arr; + let arr: Point[2] = arr; arr[0] = Point { x: 10, y: 20 }; arr[1] = Point { x: 30, y: 40 }; print_i64(arr[0].x); diff --git a/test/test_codegen.c b/test/test_codegen.c index 0d36beb..80eeff5 100644 --- a/test/test_codegen.c +++ b/test/test_codegen.c @@ -292,13 +292,13 @@ void test_codegen_array() { /* 构造 AST: fn main() -> i64 { - let arr: [i64; 3] = arr; + let arr: i64[3] = arr; arr[0] = 10; print_i64(arr[0]); return 0; } */ - // let arr: [i64; 3] = arr; + // let arr: i64[3] = arr; AstNode* arr_init = ast_make_ident(&a, "arr", loc_at(1, 1)); AstNode* let_stmt = ast_make_let(&a, "arr", TYPE_ARRAY, true, false, arr_init, NULL, TYPE_I64, NULL, 3, loc_at(1, 1)); diff --git a/test/test_sema.c b/test/test_sema.c index 6b5d0b1..16b19c7 100644 --- a/test/test_sema.c +++ b/test/test_sema.c @@ -265,7 +265,7 @@ void test_array_ok() { Arena a = arena_create(1); size_t tc; ErrorInfo lex_err = {0}; Token* toks = lex(&a, - "fn main() { let arr: [i64; 3] = arr; arr[0]; return; }", + "fn main() { let arr: i64[3] = arr; arr[0]; return; }", "test", &tc, &lex_err); ASSERT(toks != NULL); ErrorInfo parse_err = {0}; @@ -282,7 +282,7 @@ void test_array_index_type_error() { Arena a = arena_create(1); size_t tc; ErrorInfo lex_err = {0}; Token* toks = lex(&a, - "fn main() { let arr: [i64; 3] = arr; arr[true]; return; }", + "fn main() { let arr: i64[3] = arr; arr[true]; return; }", "test", &tc, &lex_err); ASSERT(toks != NULL); ErrorInfo parse_err = {0}; @@ -316,7 +316,7 @@ void test_array_assign_ok() { Arena a = arena_create(1); size_t tc; ErrorInfo lex_err = {0}; Token* toks = lex(&a, - "fn main() { let arr: [i64; 3] = arr; arr[0] = 42; return; }", + "fn main() { let arr: i64[3] = arr; arr[0] = 42; return; }", "test", &tc, &lex_err); ASSERT(toks != NULL); ErrorInfo parse_err = {0};