diff --git a/.gitignore b/.gitignore
index 21e01df..77c9d91 100644
--- a/.gitignore
+++ b/.gitignore
@@ -40,3 +40,4 @@ target/
### Snow 虚拟机指令 ###
*.water
+/.lingma/
diff --git a/README.md b/README.md
index 9df5b5f..8593611 100644
--- a/README.md
+++ b/README.md
@@ -69,7 +69,10 @@ Snow 语言受到 LLM 驱动代码生成趋势的启发,强调简单而清晰的
[https://gitee.com/jcnc-org/snow/releases](https://gitee.com/jcnc-org/snow/releases)
## 相关文档
-[Snow-Lang 语法](docs/Snow-Lang-Syntax/Snow-Lang-Syntax.md)
+[Snow-Lang 指南](docs/Snow-Lang-Syntax/Snow-Lang-Syntax.md)
+
+[Snow-Lang 语法规范](docs/Snow-Lang-Syntax/Snow-Lang-Grammar-Specification.md)
+
[Git 管理规范](docs/Snow-Lang-Git-Management/Snow-Lang-Git-Management.md)
@@ -388,11 +391,11 @@ module: Math
body:
declare num1:int = 1
loop:
- initializer:
+ init:
declare counter:int = 1
- condition:
+ cond:
counter <= n
- update:
+ step:
counter = counter + 1
body:
num1 = num1 * counter
diff --git a/docs/Snow-Lang-Syntax/Snow-Lang-Grammar-Specification.md.md b/docs/Snow-Lang-Syntax/Snow-Lang-Grammar-Specification.md.md
new file mode 100644
index 0000000..a529bf4
--- /dev/null
+++ b/docs/Snow-Lang-Syntax/Snow-Lang-Grammar-Specification.md.md
@@ -0,0 +1,585 @@
+# Snow‑Lang 语法规范
+
+---
+
+## 0 · 符号约定
+
+* ⟦ … ⟧:可选项(0 或 1 次)
+* { … }\*:可重复项(0 次或多次)
+
+---
+
+## 1 · 词汇结构
+
+### 1.1 编码与字符集
+
+源文件采用 UTF‑8 编码。除注释外,标识符只允许英文大小写字母 (A‑Z a‑z)、数字 (0‑9) 与下划线 _;首字符不能为数字。
+
+```ebnf
+identifier ::= [A-Za-z_][A-Za-z0-9_]* ;
+```
+
+* **区分大小写**:Foo 与 foo 为不同标识符。
+* 保留字 (见 §1.3) **禁止** 用作标识符。
+
+### 1.2 分隔符与强制空白
+
+相邻两个标记之间 **推荐** 至少以 1 个空白字符分隔,除非记号本身带有定界符 (( ) , : = < > 等)。示例:
+
+```snow
+module: Foo // 推荐
+module:Foo // 不推荐
+```
+
+### 1.3 保留关键字
+
+```
+module import end module globals struct end struct
+function end function params returns body end body
+declare if then else end if loop init cond step
+end loop break continue self
+```
+
+以上列表 **均为关键词**,大小写固定,不能作为标识符。
+
+### 1.4 文字量 (Literal)
+
+* **整型**:123 0 -42
+* **浮点**:3.14 0.0
+* **布尔**:true false
+* **字符串**:未来版本保留;当前规范未定义。
+
+### 1.5 注释
+
+* **单行注释**:以 // 起,至当行行尾。
+* **多行注释**:/* … */ 可跨行。**不可嵌套**;嵌套会在最内层 */ 处终止外层,导致编译错误。
+
+---
+
+### 1.6 换行与缩进
+
+* **只有换行有语义**:以行末冒号(:)打开一个块时(如 module:、function:、if、loop: 等),块体**必须另起新行**。
+* **缩进没有语义**:缩进仅用于提高代码可读性,对语法无影响。缩进不一致不会报错。
+* 块体通过显式关闭关键字(如 end module、end function 等)结束。
+* 若关闭关键字与开始关键字之间的缩进不一致,不会报错,仍以关闭关键字为准。
+
+> 块体结构完全由行分隔和显式关闭关键字决定,缩进仅为美观,不影响代码执行。
+
+---
+
+## 2 · 模块与导入
+
+### 2.1 模块声明
+
+```snow
+module:
+ …
+end module
+```
+
+* 一个源文件只能出现 **一次** module: 声明,且文件名与模块名无必然关系。
+* 模块名可使用点号(.)分隔表示包层级,例如 util.math。
+* **允许** 不同文件夹下声明同名模块,但模块全名(含包路径,用点分隔)在全项目中必须唯一。
+* 若项目中出现重复的模块全名,编译阶段将报重定义错误。
+
+例如:
+> src/util/math.snow // module: util.math
+> src/core/math.snow // module: core.math
+>
+> 两者都声明了 module: math,但由于包路径不同(util.math 与 core.math),互不冲突。
+
+### 2.2 导入
+
+```snow
+import: ⟦ as ⟧, ⟦ as ⟧, …
+```
+
+* **别名 (Alias)** 可为任何合法标识符,放在 as 关键字之后。
+* **重复导入**:对同一模块多次导入(无论是否带 alias)只解析一次,其余忽略告警。
+* **循环依赖**:当前规范未定义,若出现编译器可拒绝或延迟解析。
+* **子模块**(诸如 A.B)暂不支持。
+
+### 2.3 全路径引用
+
+* 跨模块引用必须使用 _Prefix_._Name_,其中 *Prefix* 是模块名或导入时的别名。
+ 例如:Math.Point 或 M.sin。
+* **解析顺序**:未加前缀的标识符只在本模块查找;找不到则视为编译错误,不会隐式搜索导入模块。
+
+---
+
+## 3 · 命名与作用域
+
+### 3.1 作用域层级
+
+1. **模块顶层**:全局变量、结构体、模块级函数。
+2. **结构体内部**:字段、方法、构造函数。
+3. **函数/方法**:形参与局部变量。
+4. **局部嵌套块** (if / loop 等) 的局部变量。
+
+### 3.2 唯一性规则
+
+* **模块顶层唯一**:同一模块的 *结构体名*、*模块级函数名*、*全局变量名* **不得重名**。
+* **结构体内部**:字段名与方法名不得相同;**允许有多个与结构体名同名的函数(即构造函数重载),但其参数签名必须互不相同。**
+* **构造函数重载**:结构体内部可以声明多个与结构体名同名的函数作为构造函数,参数类型与数量必须不同,否则属于 DuplicateName 错误。
+* **跨层级遮蔽**:内层可定义与外层同名标识符(除关键字限制外),遵循最近作用域原则。
+
+### 3.3 访问控制约定
+
+* **私有成员与方法**:以单个下划线 `_` 开头的变量名、字段名或方法名,**仅在其所属结构体或模块内部可见**。外部不可访问,编译器应报错 `AccessDenied`。
+ - 例如 `_foo`, `_barMethod`。
+* **公有成员与方法**:非下划线开头的变量、字段、方法,默认为公有。可在模块外部通过模块名/别名前缀访问。
+
+#### 影响范围
+- **模块级变量与函数**:`globals` 和 `function` 语句声明的以 `_` 开头者,仅限本模块访问。
+- **结构体字段与方法**:声明为 `_name`、`_doSomething` 的,仅结构体本身或其方法体可访问。
+---
+
+#### 访问示例
+
+```snow
+// module: foo
+globals:
+ declare _secret: int = 42 // 仅 foo 模块内部可见
+ declare visible: int = 1 // 公有
+
+function: _hidden // 仅 foo 模块内部可见
+ returns: int
+ body:
+ return 100
+ end body
+end function
+
+function: publicFunc
+ returns: int
+ body:
+ return _secret + 1 // 合法
+ end body
+end function
+
+// module: bar
+import: foo
+
+declare x: int = foo.visible // 合法
+declare y: int = foo._secret // 编译错误 AccessDenied
+declare z: int = foo._hidden() // 编译错误 AccessDenied
+```
+
+## 4 · 声明语法
+
+### 4.1 全局变量
+
+```snow
+globals:
+ declare VarName: Type ⟦= Expr⟧
+```
+
+* 后续对该变量赋值时 **不得** 使用 declare。
+
+### 4.2 结构体
+
+```snow
+struct: StructName
+ declare field1: Type1
+ declare field2: Type2
+ …
+
+ // ──────────── 构造函数(可以不存在, 可重载) ──────────────
+ function: StructName
+ params:
+ declare p1: Type1
+ …
+ body:
+ self.field1 = p1
+ …
+ end body
+ end function
+
+ function: StructName
+ params:
+ declare q1: TypeQ
+ declare q2: TypeQ
+ body:
+ // ...
+ end body
+ end function
+ // ...可继续声明更多参数签名各异的构造函数...
+ // ─────────────────────────────────────────────
+
+ // ────────── 结构体内函数 (可以不存在) ──────────
+ function: method1
+ ⟦params:
+ declare x: TypeX
+ …⟧
+ returns: ReturnType
+ body:
+ …
+ end body
+ end function
+ // ─────────────────────────────────────────────
+
+end struct
+```
+
+**实例化**:
+
+* declare p: Point = Point(1, 2)
+* declare p2: Point = Point(3)
+
+- 实参顺序 = 构造函数 params: 声明顺序;与字段声明顺序无关。
+- **构造函数重载时**,调用 Point(...) 时根据参数数量和类型匹配唯一的构造函数。若无匹配或多重匹配,则为编译错误。
+- 不支持命名实参、缺省实参或字段名字面量初始化。
+
+### 4.3 函数
+
+```snow
+function: FuncName
+ returns: Type // 无返回值的时候写 void
+ ⟦params:
+ declare x: TypeX // 无参数的时候不写 params
+ …⟧
+ body:
+ …
+ end body
+end function
+```
+
+* **返回检查**:若 returns: 指定类型非 void,所有控制流路径必须显式 return 该类型值。
+* 在 loop 内或经 break 跳出后能到达的路径亦计入检查;若缺失,编译错误。
+
+---
+
+## 5 · 语句
+
+### 5.1 变量声明与赋值
+
+```snow
+declare x: int = 0
+x = 1
+```
+
+* 同一作用域中 declare 仅能出现一次。
+
+### 5.2 条件语句
+
+```snow
+if Condition then
+ …
+else
+ …
+end if
+```
+
+* Condition 类型必须为 bool。
+
+### 5.3 循环语句
+
+```snow
+loop:
+ init:
+ declare i: int = 0
+ cond:
+ i < 10
+ step:
+ i = i + 1
+ body:
+ …
+ end body
+end loop
+```
+
+* **作用域**:init 块声明的变量仅在本 loop 的 init/cond/step/body 有效。
+* break 立即终止当前循环;continue 跳过剩余 body,执行 step → cond。
+
+---
+
+## 6 · 类型系统
+
+### 6.1 数值类型
+
+Snow-Lang 支持下列**数值类型**,用于声明变量、参数、结构体字段、函数返回等:
+
+| 类型名 | 关键字 | 位数 | 描述 |
+|----------|--------|----|---------------------------|
+| byte8 | byte | 8 | 8 位有符号整数 |
+| short16 | short | 16 | 16 位有符号整数 |
+| int32 | int | 32 | 32 位有符号整数(默认整数类型) |
+| long64 | long | 64 | 64 位有符号整数 |
+| float32 | float | 32 | 32 位 IEEE-754 浮点数 |
+| double64 | double | 64 | 64 位 IEEE-754 浮点数(默认浮点类型) |
+
+**说明**
+* 没有无符号整型,所有整型均为有符号。
+* `int` 为整数常量与变量的默认类型。
+* `double` 为浮点常量与变量的默认类型。
+* `bool` 类型只表示真/假,不允许与数值类型直接互转。
+
+#### 数值字面量后缀
+
+为指定具体类型,可在数值字面量后加后缀字母(大小写均可):
+
+| 后缀 | 类型 | 例子 |
+|----|--------|----------|
+| b | byte | 7b, -2B |
+| s | short | 123s |
+| i | int | 100i |
+| l | long | 5l, 123L |
+| f | float | 3.14f |
+| d | double | 1.0d |
+
+- 没有后缀的整数字面量自动为 `int`。
+- 没有后缀的浮点字面量自动为 `double`。
+
+**示例:**
+```snow
+declare a: int = 7 // int (默认)
+declare b: long = 9l // long
+declare c: float = 2.5f // float
+declare d: double = 2.5 // double (默认)
+declare e: byte = 127b // byte
+declare f: short = 100s // short
+````
+
+---
+
+### 6.2 布尔类型
+
+* 关键字为 `bool`
+* 字面量为 `true` 或 `false`
+* 仅用于逻辑判断、条件分支,不与整型互转
+
+---
+
+### 6.3 数组类型
+
+支持一维和多维数组。数组类型以 `T[]` 表示元素类型为 T 的一维数组,多维数组以 `T[][]`、`T[][][]` 依次类推。
+
+#### 声明与初始化
+
+````snow
+declare arr: int[] = [1, 2, 3]
+declare matrix: double[][] = [
+ [1.1, 2.2],
+ [3.3, 4.4]
+]
+declare cube: bool[][][] = [
+ [[true, false], [false, true]],
+ [[false, false], [true, true]]
+]
+````
+
+#### 访问与赋值
+
+````snow
+arr[0] = 10
+matrix[1][1] = 5.6
+declare x: int = arr[2]
+declare y: double = matrix[0][1]
+````
+
+---
+
+### 6.4 结构体类型
+
+* 使用 `struct` 关键字声明
+* 结构体类型为用户自定义类型,**值类型**(赋值、传参时会拷贝整个结构体)
+* 字段类型可以为任何合法类型(包括数组、其它结构体)
+
+````snow
+struct: Point
+ declare x: int
+ declare y: int
+end struct
+
+declare a: Point = Point(1, 2)
+````
+
+---
+
+### 6.5 传值说明
+
+* **所有变量、参数、返回值**均为**值传递**(按值拷贝)
+* 结构体、数组在赋值与传参时,均会复制整个值;后续修改不会影响原对象
+
+
+---
+
+## 7 · 名字解析算法(概览)
+
+1. **输入**:未限定前缀的标识符 N,当前作用域 S。
+2. 自内向外遍历作用域链查找 N;首次匹配即确定绑定。
+3. 若遍历至模块顶层仍未匹配,编译错误 *UnresolvedIdentifier*。
+4. 限定名 Prefix.N:直接在模块表中查 Prefix(包括别名),成功后在该模块顶层查找 N;找不到即 *UnresolvedQualifiedIdentifier*。
+
+---
+
+## 8 · 编译单位与入口
+
+* **单一入口**:编译器需指定某模块某函数作为启动入口。
+* **模块初始化**:globals 块中的带初值变量在程序启动时自顶向下按出现顺序初始化;不同模块按依赖拓扑顺序初始化(循环依赖未定义)。
+
+---
+
+## 9 · 错误分类
+
+| 编译期错误代码 | 产生条件 |
+|----------------------|----------------------------|
+| DuplicateName | 违反唯一性规则;结构体内有参数签名完全相同的构造函数 |
+| UnresolvedIdentifier | 名字无法解析 |
+| ReturnMissing | 非 void 函数缺少 return |
+| TypeMismatch | 赋值或返回类型不兼容 |
+| ImportCycle | (可选)检测到循环依赖 |
+| CtorAmbiguous | 构造函数重载时参数匹配不唯一 |
+| CtorNotFound | 构造函数重载时无匹配参数签名 |
+| AccessDenied | 访问了以 `_` 开头的私有变量或方法但不在允许范围 |
+
+---
+
+
+## 10 · 完整示例
+
+````snow
+module: RectExample
+ import: Geometry
+
+ struct: Point
+ declare x: int
+ declare y: int
+
+ // 构造函数1:两个参数
+ function: Point
+ params:
+ declare x: int
+ declare y: int
+ body:
+ self.x = x
+ self.y = y
+ end body
+ end function
+
+ // 构造函数2:一个参数
+ function: Point
+ params:
+ declare xy: int
+ body:
+ self.x = xy
+ self.y = xy
+ end body
+ end function
+ end struct
+
+ struct: Rectangle
+ declare left_top: Point
+ declare right_bottom: Point
+
+ function: Rectangle
+ params:
+ declare x1: int
+ declare y1: int
+ declare x2: int
+ declare y2: int
+ body:
+ self.left_top = Point(x1, y1)
+ self.right_bottom = Point(x2, y2)
+ end body
+ end function
+
+ function: Rectangle
+ params:
+ declare width: int
+ declare height: int
+ body:
+ self.left_top = Point(0, 0)
+ self.right_bottom = Point(width, height)
+ end body
+ end function
+
+ function: width
+ returns: int
+ body:
+ return self.right_bottom.x - self.left_top.x
+ end body
+ end function
+
+ function: height
+ returns: int
+ body:
+ return self.right_bottom.y - self.left_top.y
+ end body
+ end function
+
+ function: area
+ returns: int
+ body:
+ return self.width() * self.height()
+ end body
+ end function
+ end struct
+
+ function: main
+ returns: int
+ body:
+ declare rect1: Rectangle = Rectangle(0, 0, 10, 10)
+ declare rect2: Rectangle = Rectangle(5, 6)
+ declare result: int = 0
+ if rect1.area() > 50 then
+ loop:
+ init:
+ declare i: int = 1
+ cond:
+ i <= rect1.width()
+ step:
+ i = i + 1
+ body:
+ if i == 3 then
+ continue
+ end if
+ if i == 8 then
+ break
+ end if
+ result = result + i
+ end body
+ end loop
+ else
+ result = rect1.area()
+ end if
+ return result
+ end body
+ end function
+
+end module
+````
+
+---
+
+## 11 · 构造函数重载示例
+
+**示例:**
+
+````snow
+struct: Point
+ declare x: int
+ declare y: int
+
+ function: Point
+ params:
+ declare x: int
+ declare y: int
+ body:
+ self.x = x
+ self.y = y
+ end body
+ end function
+
+ function: Point
+ params:
+ declare xy: int
+ body:
+ self.x = xy
+ self.y = xy
+ end body
+ end function
+end struct
+
+declare a: Point = Point(1, 2) // 匹配第一个构造函数
+declare b: Point = Point(5) // 匹配第二个构造函数
+````
\ No newline at end of file
diff --git a/docs/Snow-Lang-Syntax/Snow-Lang-Syntax.md b/docs/Snow-Lang-Syntax/Snow-Lang-Syntax.md
index 265b4b1..2ac5fdd 100644
--- a/docs/Snow-Lang-Syntax/Snow-Lang-Syntax.md
+++ b/docs/Snow-Lang-Syntax/Snow-Lang-Syntax.md
@@ -102,14 +102,14 @@ x = y + 1
if 语句的形式如下,else 是可选的:
```snow
-if condition then
+if cond then
// 条件成立执行的代码
else
// 以上条件不成立执行的代码
end if
```
-condition 可以是表达式(结果为 bool 类型)或者 bool 字面量
+cond 可以是表达式(结果为 bool 类型)或者 bool 字面量
例:
@@ -134,14 +134,14 @@ end module
loop 语句的形式如下:
```snow
loop:
- initializer:
+ init:
// 循环开始前可声明循环变量,有且只能声明一个
declare i: int = 1
- condition:
+ cond:
// 循环条件,成立则执行 body 的代码,
// 不成立则退出循环,有且只能写一条
i <= 100
- update:
+ step:
// 循环体执行完后执行的代码,有且只能写一条
i = i + 1
body:
@@ -158,11 +158,11 @@ module: Main
body:
declare sum: int = 0
loop:
- initializer:
+ init:
declare i: int = 1
- condition:
+ cond:
i <= 100
- update:
+ step:
i = i + 1
body:
sum = sum + i
diff --git a/lib/math/factorial/factorial.snow b/lib/math/factorial/factorial.snow
index 46749dd..82a6dbf 100644
--- a/lib/math/factorial/factorial.snow
+++ b/lib/math/factorial/factorial.snow
@@ -15,11 +15,11 @@ module: Math
body:
declare num1:int = 1
loop:
- initializer:
+ init:
declare counter:int = 1
- condition:
+ cond:
counter <= n
- update:
+ step:
counter = counter + 1
body:
num1 = num1 * counter
diff --git a/lib/test/Dead_loop.snow b/lib/test/Dead_loop.snow
index 5f73bfb..f2a1a98 100644
--- a/lib/test/Dead_loop.snow
+++ b/lib/test/Dead_loop.snow
@@ -3,11 +3,11 @@ function: main
return_type: int
body:
loop:
- initializer:
+ init:
declare i:int = 0
- condition:
+ cond:
1 == 1
- update:
+ step:
i = i + 1
body:
diff --git a/playground/Demo/Demo5/Main.snow b/playground/Demo/Demo5/Main.snow
index 75ae75f..c475980 100644
--- a/playground/Demo/Demo5/Main.snow
+++ b/playground/Demo/Demo5/Main.snow
@@ -5,11 +5,11 @@ module: Main
body:
declare b1: boolean = true
loop:
- initializer:
+ init:
declare i:int = 0
- condition:
+ cond:
b1
- update:
+ step:
i = i + 1
body:
diff --git a/playground/Demo/Demo9/Main.snow b/playground/Demo/Demo9/Main.snow
index 46749dd..82a6dbf 100644
--- a/playground/Demo/Demo9/Main.snow
+++ b/playground/Demo/Demo9/Main.snow
@@ -15,11 +15,11 @@ module: Math
body:
declare num1:int = 1
loop:
- initializer:
+ init:
declare counter:int = 1
- condition:
+ cond:
counter <= n
- update:
+ step:
counter = counter + 1
body:
num1 = num1 * counter
diff --git a/src/main/java/org/jcnc/snow/compiler/ir/builder/StatementBuilder.java b/src/main/java/org/jcnc/snow/compiler/ir/builder/StatementBuilder.java
index 30d672a..7472269 100644
--- a/src/main/java/org/jcnc/snow/compiler/ir/builder/StatementBuilder.java
+++ b/src/main/java/org/jcnc/snow/compiler/ir/builder/StatementBuilder.java
@@ -155,18 +155,18 @@ public class StatementBuilder {
* @param loop 循环节点
*/
private void buildLoop(LoopNode loop) {
- if (loop.initializer() != null) build(loop.initializer());
+ if (loop.init() != null) build(loop.init());
String lblStart = ctx.newLabel();
String lblEnd = ctx.newLabel();
// 循环开始标签
InstructionFactory.label(ctx, lblStart);
// 条件不满足则跳出循环
- emitConditionalJump(loop.condition(), lblEnd);
+ emitConditionalJump(loop.cond(), lblEnd);
// 构建循环体
buildStatements(loop.body());
// 更新部分(如 for 的 i++)
- if (loop.update() != null) build(loop.update());
+ if (loop.step() != null) build(loop.step());
// 跳回循环起点
InstructionFactory.jmp(ctx, lblStart);
diff --git a/src/main/java/org/jcnc/snow/compiler/lexer/token/TokenFactory.java b/src/main/java/org/jcnc/snow/compiler/lexer/token/TokenFactory.java
index e6463f4..e94c54b 100644
--- a/src/main/java/org/jcnc/snow/compiler/lexer/token/TokenFactory.java
+++ b/src/main/java/org/jcnc/snow/compiler/lexer/token/TokenFactory.java
@@ -25,7 +25,7 @@ public class TokenFactory {
/**
* 语言的保留关键字集合。
*/
- private static final Set KEYWORDS = Set.of("module", "function", "parameter", "return_type", "body", "end", "if", "then", "else", "loop", "declare", "return", "import", "initializer", "condition", "update");
+ private static final Set KEYWORDS = Set.of("module", "function", "parameter", "return_type", "body", "end", "if", "then", "else", "loop", "declare", "return", "import", "init", "cond", "step");
/**
* 内置类型名称集合,如 int、string 等。
diff --git a/src/main/java/org/jcnc/snow/compiler/parser/ast/LoopNode.java b/src/main/java/org/jcnc/snow/compiler/parser/ast/LoopNode.java
index 2ba283e..153352c 100644
--- a/src/main/java/org/jcnc/snow/compiler/parser/ast/LoopNode.java
+++ b/src/main/java/org/jcnc/snow/compiler/parser/ast/LoopNode.java
@@ -14,16 +14,16 @@ import java.util.List;
* 每一部分均对应为 AST 中的子节点,便于进一步语义分析与代码生成。
*
*
- * @param initializer 在循环开始前执行的初始化语句
- * @param condition 每次迭代前评估的条件表达式,控制循环是否继续
- * @param update 每轮迭代完成后执行的更新语句
- * @param body 循环体语句列表,表示循环主体执行逻辑
- * @param context 节点的上下文信息(包含行号、列号、文件名等)
+ * @param init 在循环开始前执行的初始化语句
+ * @param cond 每次迭代前评估的条件表达式,控制循环是否继续
+ * @param step 每轮迭代完成后执行的更新语句
+ * @param body 循环体语句列表,表示循环主体执行逻辑
+ * @param context 节点的上下文信息(包含行号、列号、文件名等)
*/
public record LoopNode(
- StatementNode initializer,
- ExpressionNode condition,
- StatementNode update,
+ StatementNode init,
+ ExpressionNode cond,
+ StatementNode step,
List body,
NodeContext context
) implements StatementNode {
diff --git a/src/main/java/org/jcnc/snow/compiler/parser/function/ASTPrinter.java b/src/main/java/org/jcnc/snow/compiler/parser/function/ASTPrinter.java
index c12edb3..91ed077 100644
--- a/src/main/java/org/jcnc/snow/compiler/parser/function/ASTPrinter.java
+++ b/src/main/java/org/jcnc/snow/compiler/parser/function/ASTPrinter.java
@@ -86,9 +86,9 @@ public class ASTPrinter {
case AssignmentNode(String variable, ExpressionNode value, NodeContext _) ->
System.out.println(pad + variable + " = " + value);
case IfNode(
- ExpressionNode condition, List thenBranch, List elseBranch, NodeContext _
+ ExpressionNode cond, List thenBranch, List elseBranch, NodeContext _
) -> {
- System.out.println(pad + "if " + condition);
+ System.out.println(pad + "if " + cond);
for (StatementNode stmt : thenBranch) {
print(stmt, indent + 1);
}
@@ -100,13 +100,13 @@ public class ASTPrinter {
}
}
case LoopNode(
- StatementNode initializer, ExpressionNode condition, StatementNode update, List body,
+ StatementNode init, ExpressionNode cond, StatementNode step, List body,
NodeContext _
) -> {
System.out.println(pad + "loop {");
- print(initializer, indent + 1);
- System.out.println(pad + " condition: " + condition);
- System.out.println(pad + " update: " + update);
+ print(init, indent + 1);
+ System.out.println(pad + " cond: " + cond);
+ System.out.println(pad + " step: " + step);
System.out.println(pad + " body {");
for (StatementNode stmt : body) {
print(stmt, indent + 2);
diff --git a/src/main/java/org/jcnc/snow/compiler/parser/statement/LoopStatementParser.java b/src/main/java/org/jcnc/snow/compiler/parser/statement/LoopStatementParser.java
index c1a9c66..7ffeb74 100644
--- a/src/main/java/org/jcnc/snow/compiler/parser/statement/LoopStatementParser.java
+++ b/src/main/java/org/jcnc/snow/compiler/parser/statement/LoopStatementParser.java
@@ -24,23 +24,23 @@ import java.util.Map;
* 该语法结构参考了传统的 for-loop,并将其拆解为命名的语义区块:
* {@code
* loop:
- * initializer:
- * declare i:int = 0
- * condition:
- * i < 10
- * update:
- * i = i + 1
- * body:
- * print(i)
- * end body
+ * init:
+ * declare i: int = 0
+ * cond:
+ * i < 10
+ * step:
+ * i = i + 1
+ * body:
+ * …
+ * end body
* end loop
* }
*
* 各区块说明:
*
- * - {@code initializer}:初始化语句,通常为变量声明。
- * - {@code condition}:循环判断条件,必须为布尔或数值表达式。
- * - {@code update}:每轮执行后更新逻辑,通常为赋值语句。
+ * - {@code init}:初始化语句,通常为变量声明。
+ * - {@code cond}:循环判断条件,必须为布尔或数值表达式。
+ * - {@code step}:每轮执行后更新逻辑,通常为赋值语句。
* - {@code body}:主执行语句块,支持任意多条语句。
*
* 本类依赖 {@link FlexibleSectionParser} 实现各区块的统一处理,确保结构明确、可扩展。
@@ -75,49 +75,49 @@ public class LoopStatementParser implements StatementParser {
ParserUtils.matchHeader(ts, "loop");
// 使用数组模拟引用以便在 lambda 中写入(Java 不支持闭包内修改局部变量)
- final StatementNode[] initializer = new StatementNode[1];
- final ExpressionNode[] condition = new ExpressionNode[1];
- final AssignmentNode[] update = new AssignmentNode[1];
+ final StatementNode[] init = new StatementNode[1];
+ final ExpressionNode[] cond = new ExpressionNode[1];
+ final AssignmentNode[] step = new AssignmentNode[1];
final List body = new ArrayList<>();
// 定义各命名区块的识别与处理逻辑
Map sections = new HashMap<>();
- // initializer 区块:仅支持一条语句,通常为 declare
- sections.put("initializer", new FlexibleSectionParser.SectionDefinition(
- ts1 -> ts1.peek().getLexeme().equals("initializer"),
+ // init 区块:仅支持一条语句,通常为 declare
+ sections.put("init", new FlexibleSectionParser.SectionDefinition(
+ ts1 -> ts1.peek().getLexeme().equals("init"),
(ctx1, ts1) -> {
- ParserUtils.matchHeader(ts1, "initializer");
- initializer[0] = StatementParserFactory.get(ts1.peek().getLexeme()).parse(ctx1);
+ ParserUtils.matchHeader(ts1, "init");
+ init[0] = StatementParserFactory.get(ts1.peek().getLexeme()).parse(ctx1);
ParserUtils.skipNewlines(ts1);
}
));
- // condition 区块:支持任意可解析为布尔的表达式
- sections.put("condition", new FlexibleSectionParser.SectionDefinition(
- ts1 -> ts1.peek().getLexeme().equals("condition"),
+ // cond 区块:支持任意可解析为布尔的表达式
+ sections.put("cond", new FlexibleSectionParser.SectionDefinition(
+ ts1 -> ts1.peek().getLexeme().equals("cond"),
(ctx1, ts1) -> {
- ParserUtils.matchHeader(ts1, "condition");
- condition[0] = new PrattExpressionParser().parse(ctx1);
+ ParserUtils.matchHeader(ts1, "cond");
+ cond[0] = new PrattExpressionParser().parse(ctx1);
ts1.expectType(TokenType.NEWLINE);
ParserUtils.skipNewlines(ts1);
}
));
- // update 区块:目前仅支持单一变量赋值语句
- sections.put("update", new FlexibleSectionParser.SectionDefinition(
- ts1 -> ts1.peek().getLexeme().equals("update"),
+ // step 区块:目前仅支持单一变量赋值语句
+ sections.put("step", new FlexibleSectionParser.SectionDefinition(
+ ts1 -> ts1.peek().getLexeme().equals("step"),
(ctx1, ts1) -> {
// 获取当前 token 的行号、列号
int line = ctx.getTokens().peek().getLine();
int column = ctx.getTokens().peek().getCol();
- ParserUtils.matchHeader(ts1, "update");
+ ParserUtils.matchHeader(ts1, "step");
String varName = ts1.expectType(TokenType.IDENTIFIER).getLexeme();
ts1.expect("=");
ExpressionNode expr = new PrattExpressionParser().parse(ctx1);
ts1.expectType(TokenType.NEWLINE);
- update[0] = new AssignmentNode(varName, expr, new NodeContext(line, column, file));
+ step[0] = new AssignmentNode(varName, expr, new NodeContext(line, column, file));
ParserUtils.skipNewlines(ts1);
}
));
@@ -151,6 +151,6 @@ public class LoopStatementParser implements StatementParser {
ParserUtils.matchFooter(ts, "loop");
// 返回构造完成的 LoopNode
- return new LoopNode(initializer[0], condition[0], update[0], body, new NodeContext(loop_line, loop_column, file));
+ return new LoopNode(init[0], cond[0], step[0], body, new NodeContext(loop_line, loop_column, file));
}
}
diff --git a/src/main/java/org/jcnc/snow/compiler/parser/utils/ASTJsonSerializer.java b/src/main/java/org/jcnc/snow/compiler/parser/utils/ASTJsonSerializer.java
index 278a42c..51ba838 100644
--- a/src/main/java/org/jcnc/snow/compiler/parser/utils/ASTJsonSerializer.java
+++ b/src/main/java/org/jcnc/snow/compiler/parser/utils/ASTJsonSerializer.java
@@ -121,7 +121,7 @@ public class ASTJsonSerializer {
Map map = newNodeMap("Declaration");
map.put("name", d.getName());
map.put("varType", d.getType());
- map.put("initializer", d.getInitializer().map(ASTJsonSerializer::exprToMap).orElse(null));
+ map.put("init", d.getInitializer().map(ASTJsonSerializer::exprToMap).orElse(null));
yield map;
}
// 赋值语句节点
@@ -132,7 +132,7 @@ public class ASTJsonSerializer {
// 条件语句节点
case IfNode i -> {
Map map = newNodeMap("If");
- map.put("condition", exprToMap(i.condition()));
+ map.put("cond", exprToMap(i.condition()));
List