diff --git a/src/main/java/org/jcnc/snow/cli/doc/README.md b/src/main/java/org/jcnc/snow/cli/doc/README.md new file mode 100644 index 0000000000000000000000000000000000000000..b823c20010a9d3fd3bd4d96e41bbe2e4a1678919 --- /dev/null +++ b/src/main/java/org/jcnc/snow/cli/doc/README.md @@ -0,0 +1,77 @@ +# Snow Compiler - CLI 模块 + +> Snow 编程语言的命令行工具 —— 负责解析命令、组织任务编排并委托 pkg 层完成构建/运行/发布等操作 + +## 项目简介 + +**CLI(Command Line Interface)** 是 Snow 项目对外的统一入口,提供从初始化项目、解析依赖、编译、打包、运行到发布的一站式指令集。 +该模块以**薄封装/强委托**为设计目标:在 CLI 层完成参数解析、子命令分发与生命周期编排,将实际业务逻辑(编译/运行/打包/依赖解析等)委托给 `pkg` 层的任务与工具执行。 + +核心入口类 `SnowCLI` 通过注册一组 `CLICommand` 子命令(如 `build` / `compile` / `run` / `publish` 等),统一处理**全局帮助**、**版本信息**、**未知命令兜底**与**退出码约定**,并支持在将来通过 `ServiceLoader`/注册表扩展新的命令。 + +## 核心功能 + +* **统一的命令模型** + + * 抽象接口:`CLICommand`(`getName`/`getDescription`/`printUsage`/`execute`) + * 入口调度:`SnowCLI`(注册命令、解析 argv、分发执行、捕获异常并以退出码退出) + * 全局帮助与选项:`CLIUtils`(`help/-h/--help` 标志、打印全局使用说明与可用子命令列表;`Option` 记录类型) + * 版本信息:`VersionUtils#loadVersion` 读取 `version.properties` 中的 `snow.version`,`SnowCLI.SNOW_VERSION` 对外输出 + +* **命令体系(内置子命令一览)** + + * `version`:输出当前 Snow 工具版本(`VersionCommand`) + * `init`:在当前目录快速生成 `project.cloud` 示例(`InitCommand`,基于 `ProjectCloudExample`) + * `install`:解析项目并预下载依赖到本地缓存(`InstallCommand` → `DependencyResolver`) + * `generate`:依据 `project.cloud` 生成基本目录结构/骨架(`GenerateCommand` → `GenerateTask`) + * `compile`:编译源代码(可在 Local/Cloud 场景下工作,`CompileCommand` → `CompileTask`) + * `run`:运行已编译的 VM 字节码(`.water`)(`RunCommand` → `RunTask`) + * `build`:一键构建(依赖解析 → 编译 → 打包)(`BuildCommand` → `LifecycleManager` + `CompileTask`/`PackageTask`) + * `clean`:清理构建产物与本地缓存(`CleanCommand` → `CleanTask`) + * `publish`:将制品发布到远端仓库(`PublishCommand` → `PublishTask`) + +* **与 pkg 层的解耦与编排** + + * DSL 解析:`CloudDSLParser` 读取 `project.cloud` 为 `Project` 模型 + * 依赖解析与缓存:`DependencyResolver`(默认缓存目录位于用户主目录 `~/.snow/cache`) + * 生命周期编排:`LifecycleManager` / `LifecyclePhase` 注册并顺序执行任务(如 `RESOLVE_DEPENDENCIES` / `COMPILE` / `PACKAGE` / `PUBLISH` / `CLEAN` / `INIT` 等) + * 具体任务:`CompileTask`、`RunTask`、`PackageTask`、`GenerateTask`、`CleanTask`、`PublishTask`(CLI 仅做参数组装与委托) + +* **错误处理与退出码约定** + + * 未知命令:打印全局帮助与可用子命令列表 + * `--help`:打印对应子命令使用说明并以 **0** 退出 + * 执行异常:捕获并打印错误信息,以 **1** 退出 + * 正常结束:各命令返回 **0** 表示成功 + +* **可扩展性与可维护性** + + * 子命令实现无状态、线程安全,便于后续通过**注册表或 `ServiceLoader`** 插拔扩展 + * 入口类集中注册命令,统一管理**命令名到构造器**的映射(`Map>`) + * 通过 `Mode` / `SnowConfig`(导入于 `org.jcnc.snow.common`)为不同环境(如 Local / Cloud)预留模式切换与参数来源 + +## 模块结构 + +``` +cli/ + ├── SnowCLI.java // CLI 入口:解析 argv、注册/分发子命令、处理全局帮助与退出码 + │ + ├── api/ + │ └── CLICommand.java // 命令抽象接口:name/description/printUsage/execute + │ + ├── commands/ // 具体子命令实现(薄封装,委托 pkg 层任务) + │ ├── BuildCommand.java // 构建:解析依赖 → 编译 → 打包(LifecycleManager + CompileTask/PackageTask) + │ ├── CleanCommand.java // 清理:清除 build 产物与缓存(CleanTask) + │ ├── CompileCommand.java // 编译:支持本地/云两种参数来源(CompileTask) + │ ├── GenerateCommand.java // 生成:根据 project.cloud 生成骨架(GenerateTask) + │ ├── InitCommand.java // 初始化:输出 project.cloud 示例(ProjectCloudExample) + │ ├── InstallCommand.java // 安装依赖:解析并预热依赖缓存(DependencyResolver) + │ ├── PublishCommand.java // 发布:将制品上传到远程仓库(PublishTask) + │ ├── RunCommand.java // 运行:执行 .water 字节码(RunTask) + │ └── VersionCommand.java // 版本:打印 snow 版本号 + │ + └── utils/ + ├── CLIUtils.java // 全局帮助/选项与用法输出(含 Option 记录类型) + ├── ProjectCloudExample.java // 示例 DSL(project.cloud)模板内容 + └── VersionUtils.java // 从 version.properties 读取 snow.version +``` diff --git a/src/main/java/org/jcnc/snow/common/doc/README.md b/src/main/java/org/jcnc/snow/common/doc/README.md new file mode 100644 index 0000000000000000000000000000000000000000..5dcf11465bbc8ae71b4f066dc0254751d5227b06 --- /dev/null +++ b/src/main/java/org/jcnc/snow/common/doc/README.md @@ -0,0 +1,41 @@ +# Snow Compiler - Common 公共模块 + +> Snow 编译器的通用基础能力 —— 统一运行模式/调试输出与字符串转义工具 + +## 项目简介 + +**Common** 是 Snow 编译器项目的基础工具模块,提供两类核心能力: +1)统一的**运行/调试模式**切换与便捷的调试输出;2)在虚拟机(VM)执行阶段使用的**字符串反转义**工具。 +该模块以极简 API 抽象暴露通用能力,供编译阶段与运行时组件复用。 + +## 核心功能 + +* **运行模式与调试输出** + + * 模式枚举:`Mode` —— `RUN`(运行)、`DEBUG`(调试) + * 全局配置:`SnowConfig` + * 运行模式:`public static Mode MODE`(默认 `RUN`) + * 判定方法:`isDebug()` / `isRun()` + * 调试输出(仅 `DEBUG` 模式生效): + * `print(String msg)` —— 行输出 + * `print(String fmt, Object... args)` —— `printf` 风格格式化输出 + +* **字符串转义(运行期反转义)** + + * 工具类:`StringEscape` + * 反转义:`unescape(String src)` + * 支持:`\n`、`\t`、`\r`、`\b`、`\f`、`\\`、`\"`、`\'` + * 支持 Unicode:`\uXXXX`(十六进制 4 位) + * 容错策略: + * 非法 `\u` 十六进制序列:以原样 `\uXXXX` 输出 + * 字符串末尾单个反斜杠:按原样 `\` 输出 + * 未定义转义:输出其字面字符(如 `\x` → `x`) + +## 模块结构 + +``` +common/ // 公共工具模块(包名:org.jcnc.snow.common) + ├── Mode.java // 运行/调试模式枚举:RUN / DEBUG + ├── SnowConfig.java // 全局模式设置与调试输出工具(print / printf、isDebug / isRun) + └── StringEscape.java // 字符串反转义工具:unescape(含 \uXXXX 支持与容错) +``` \ No newline at end of file diff --git a/src/main/java/org/jcnc/snow/compiler/backend/doc/README.md b/src/main/java/org/jcnc/snow/compiler/backend/doc/README.md index 18088332a9cf04cd49628eab88ed42416bfe4579..743fbac9e4b794b2c14d6b958348e35acd166f9f 100644 --- a/src/main/java/org/jcnc/snow/compiler/backend/doc/README.md +++ b/src/main/java/org/jcnc/snow/compiler/backend/doc/README.md @@ -1,56 +1,106 @@ -# Snow Compiler - 后端模块 +# Snow Compiler - Backend(IR→VM)模块 -> Snow 编译器的后端模块 —— 负责将中间表示(IR)翻译、优化并生成虚拟机指令序列(VM) +> Snow 编译器的后端代码生成模块 —— 负责把 IR 翻译为 Snow虚拟机(Snow VM)的指令序列 ## 项目简介 -**后端模块(Backend)** 是 [Snow 编译器]() 的核心组成部分之一,承接中间表示(IR)与运行时虚拟机(VM)之间的桥梁。 -它主要完成以下工作: +**Backend(IR→VM)** 模块承接 IR 层产物,完成**寄存器分配**、**操作码映射与类型提升**、**指令选择与输出组装**,最终生成可在 Snow VM 上执行的指令流。 +模块采用“**指令生成器(InstructionGenerator)+ 注册表**”的可插拔架构:每种 IR 指令对应一个生成器;`VMCodeGenerator` 负责分发与调度;`VMProgramBuilder` 负责落盘(emit)、标签/调用回填(fixup)与函数边界管理。 -1. **寄存器分配**: 将 IR 中的虚拟寄存器映射为物理槽号或栈槽; -2. **指令生成与调度**: 为每条 IR 指令分配对应的 VM 指令生成器,并负责调用它们输出指令文本; -3. **程序构建**: 管理函数入口、标签定义、延迟修补(fix-up)CALL/JUMP 等控制流指令地址; -4. **操作码与常量映射**: 提供 IR 操作码到 VM 操作码的映射工具,以及根据常量类型选择 PUSH/STORE 指令。 +## 核心功能 -后端模块设计注重可扩展性: 各类 IR → VM 的转换逻辑被拆分到不同的 `*Generator` 类中,新增指令只需注册新的生成器;寄存器分配和程序构建也各司其职,职责清晰,便于维护和测试。 +* **端到端的 IR→VM 翻译流水线** -## 核心功能 + * `RegisterAllocator`:为 `IRVirtualRegister` 分配 VM 局部槽位(线性扫描,顺序分配) + * `VMCodeGenerator`:按函数遍历 IR 指令,分派到具体生成器并统一收尾(`main` → `HALT`,其它 → `RET`) + * `VMProgramBuilder`:集中管理 **emit/标签/地址表/分支回填/调用回填**,以及槽位类型标注 + +* **指令生成器体系(Instruction Generators)** + + * 抽象接口:`InstructionGenerator` + * 注册表:`InstructionGeneratorProvider#defaultGenerators()` 一次性集中暴露默认实现 + * 已内置的生成器: + + * 算术/逻辑:`BinaryOpGenerator`、`UnaryOpGenerator` + * 常量加载:`LoadConstGenerator`(支持**字符串转义**、**数组/嵌套数组**、`f/L` 等**类型后缀**) + * 控制流:`LabelGenerator`、`JumpGenerator`、`CmpJumpGenerator`(比较+条件跳转,含前缀对齐与类型提升) + * 调用与返回:`CallGenerator`(含 **syscall 子命令** 与 **\_*setindex** 特例*\*)、`ReturnGenerator` + +* **寄存器与常量模型对接** + + * 槽位映射:`Map`(由 `RegisterAllocator` 产出) + * 槽位类型:`VMProgramBuilder#setSlotType/getSlotType` 维护 `'B/S/I/L/F/D/R'` 类型前缀 + * 字符串常量池:`CallGenerator#registerStringConst(regId, value)` 用于从寄存器实参恢复 syscall 子命令等 + +* **操作码映射与类型提升** + + * `IROpCodeMapper`:将 IR 的 `IROpCode` 映射成 VM 的**助记名**(如 `I_ADD/I_CE/...`) + * `OpHelper`:把助记名安全转换为 **VM 实际 opcode 数值**(与 `VMOpCode` 常量同步,脚本生成) + * `TypePromoteUtils`:数值类型**提升与转换**(`promote/convert/str`),比较前缀自动矫正(如 `I_C* ↔ L_C*`) -* **线性扫描寄存器分配**: `RegisterAllocator` 按参数优先、指令顺序为 IR 虚拟寄存器分配连续槽号。 -* **指令生成器体系**: `InstructionGenerator` 接口 + 多个 `*Generator` 实现,支持二元运算、跳转、调用、标签、常量加载、一元运算、返回等指令。 -* **生成器调度**: `VMCodeGenerator` 建立类型到生成器的映射,遍历 IR 函数体并分发调用,实现多态化指令生成。 -* **程序构建与延迟修补**: `VMProgramBuilder` 维护指令流、符号地址表及待修补列表,实现对 `CALL`/`JUMP` 等指令的延迟地址填充。 -* **操作码与常量映射**: `IROpCodeMapper` 提供 IR 操作码到 VM 指令名的静态映射;`OpHelper` 基于反射获取 VMOpCode 常量,并根据值类型(I/L/F…)选择合适的 PUSH/STORE 操作码。 +* **输出与回填(Fixup)机制** + + * **调用回填**:`emitCall(target, nArgs)` 支持三态 —— 绝对地址 / 虚调用(`@Class::method`)/ 占位回填 + * **分支回填**:`emitBranch(op, label)` 先占位,`registerLabel` 后统一修补 + * **名称解析**:支持全名/简名唯一匹配与**继承层级**的成员解析(参见 `patchRemainingFixesByInheritance`) + +* **小型 Peephole 优化** + + * `BinaryOpGenerator` 识别 `ADD_*` 的 `+0` 情形并降解为 **MOV/STORE**(避免无效运算) + * 比较指令统一产出 **0/1** 到目标槽位(`true/false` 归一为 `I` 型) ## 模块结构 ``` backend/ + ├── alloc/ // 寄存器分配 + │ └── RegisterAllocator.java // 线性扫描:为 IR 虚拟寄存器分配 VM 槽位 + │ + ├── builder/ // 后端组装与输出 + │ ├── VMCodeGenerator.java // 按函数驱动生成器,统一收尾(HALT/RET) + │ └── VMProgramBuilder.java // emit/标签/地址表/分支与调用回填/槽位类型 + │ ├── core/ - │ └── InstructionGenerator.java // 通用指令生成器接口 - ├── generator/ - │ ├── BinaryOpGenerator.java // 二元运算 - │ ├── UnaryOpGenerator.java // 一元运算 - │ ├── LoadConstGenerator.java // 常量加载 - │ ├── CallGenerator.java // 函数调用 - │ ├── ReturnGenerator.java // 函数返回 - │ ├── CmpJumpGenerator.java // 条件跳转 - │ ├── JumpGenerator.java // 无条件跳转 - │ └── LabelGenerator.java // 标签定义 - ├── alloc/ - │ └── RegisterAllocator.java // 线性扫描寄存器分配 - ├── builder/ - │ ├── VMCodeGenerator.java // 指令生成调度 - │ └── VMProgramBuilder.java // VM 程序构建与 fix-up - └── util/ - ├── IROpCodeMapper.java // IR → VM 操作码映射 - └── OpHelper.java // opcode 反射 & 常量指令辅助 + │ └── InstructionGenerator.java // 生成器接口:supportedClass()/generate(...) + │ + ├── generator/ // 各类 IR 指令 → VM 指令的具体生成器 + │ ├── InstructionGeneratorProvider.java // 默认生成器注册表 + │ ├── BinaryOpGenerator.java // 二元:算术/比较(含 +0 消解、bool 结果归一) + │ ├── UnaryOpGenerator.java // 一元:NEG/NOT 等(按槽位前缀选择 LOAD/STORE) + │ ├── LoadConstGenerator.java // 常量/数组/字符串转义与类型后缀 + │ ├── LabelGenerator.java // 标签落点 + │ ├── JumpGenerator.java // 无条件跳转 + │ ├── CmpJumpGenerator.java // 比较+条件跳转(类型提升、前缀矫正) + │ ├── CallGenerator.java // 普通调用 / 虚调用 / syscall / __setindex_* + │ └── ReturnGenerator.java // 返回(main→HALT,其它→RET) + │ + └── utils/ + ├── IROpCodeMapper.java // IROpCode → 助记名 + ├── OpHelper.java // 助记名 → VMOpCode 数值(自动生成映射) + └── TypePromoteUtils.java // 类型提升/显式转换/前缀字符工具 ``` -## 开发环境 +## 生成流程 + +1. **寄存器分配**:对每个 `IRFunction` 调用 `RegisterAllocator#allocate(fn)` → 产出 `slotMap`。 +2. **创建输出器**:`VMProgramBuilder out = new VMProgramBuilder()`。 +3. **构建代码生成器**:`VMCodeGenerator gen = new VMCodeGenerator(slotMap, out, InstructionGeneratorProvider.defaultGenerators())`。 +4. **逐函数生成**:`gen.generate(fn)`(内部:遍历 IR 指令 → 分派到对应 `InstructionGenerator` → 结束处自动发出 `HALT/RET`)。 +5. **收集结果**:`out.build()` / `out.getCode()` 取得最终 VM 指令序列(`String` 列表),可直接喂给 VM 或写出文本。 + +## 扩展指南 + +* **新增 IR 指令类型** + + 1. 定义生成器类并实现 `InstructionGenerator`; + 2. 在 `InstructionGeneratorProvider#defaultGenerators()` 注册; + 3. 如需新助记名,补充 `IROpCodeMapper` 与(若新增 VM 指令)`VMOpCode`→`OpHelper` 的映射。 + +* **支持新的数值类型或转换** + + * 在 `TypePromoteUtils` 中补充优先级/转换表与前缀字符; + * 根据需要在 `CmpJumpGenerator`/`UnaryOpGenerator` 中处理加载与前缀对齐。 -* JDK 24 或更高版本 -* Maven 构建管理 -* 推荐 IDE: IntelliJ IDEA +* **自定义调用约定** ---- + * 扩展 `VMProgramBuilder#emitCall` 或在 `CallGenerator` 中增加分支(例如内建函数、运行时服务等)。 \ No newline at end of file diff --git a/src/main/java/org/jcnc/snow/compiler/lexer/doc/README.md b/src/main/java/org/jcnc/snow/compiler/lexer/doc/README.md index f294e9346bda193a0ec43d12a72bfbefd83ae58b..70b7b140851da6d541a4f28149a198f1918b67a4 100644 --- a/src/main/java/org/jcnc/snow/compiler/lexer/doc/README.md +++ b/src/main/java/org/jcnc/snow/compiler/lexer/doc/README.md @@ -1,38 +1,119 @@ # Snow Compiler - Lexer 模块 -> Snow 编译器的前端模块 —— 负责将源代码扫描并生成 Token 流 +> Snow 编译器的词法分析(Lexing)模块 —— 把源代码字符流切分为语义化的 Token 序列,为后续语法分析/IR 构建打好基础 ## 项目简介 -**Lexer** 是 [Snow 编译器]() 项目的子模块,承担编译器前端的词法分析阶段任务。 -它负责将源代码输入,根据 Snow 语言的语法规则,识别并划分为有意义的 Token 流,为后续语法解析(Parser)提供标准输入。 - -该模块采用模块化设计,每类 Token 类型(如标识符、运算符、数字、字符串等)由独立的扫描器(Scanner)负责识别,提高了扩展性和可维护性。 +**Lexer(词法分析器)** 负责把源代码转换为一串结构化的 **Token**。 +本模块采用“**扫描器链(Chain of Scanners)+ 状态机(FSM)**”的实现思路:由统一的 `LexerEngine` 驱动多种 `TokenScanner` +子类(数字/字符串/注释/运算符/符号等),配合可扩展的 `TokenFactory`(关键字与类型识别)与 `LexerContext`(字符流与位置信息管理),形成 +**高内聚、易扩展、便于调试**的词法层。 ## 核心功能 -- **词法分析引擎**: 从源代码提取标准化 Token 流 -- **模块化扫描器体系**: 按需扩展不同类型的 Token 识别 -- **灵活的上下文管理**: 跟踪源代码位置,支持错误处理 -- **统一的 Token 工厂**: 集中创建 Token 实例 -- **工具支持**: Token 打印与调试辅助 +* **统一的 Token 模型** + * 基础抽象:`Token`(类型/词素/原文/行列)、`TokenType`(全部词法类别枚举) + * 工厂识别:`TokenFactory`(根据词素自动识别 `TYPE/KEYWORD/IDENTIFIER/BOOL_LITERAL` 等) + * 关键字: + `module/function/params/returns/body/end/if/then/else/loop/declare/return/import/init/cond/step/globals/break/continue/const/new/extends` + * 内置类型:`int/string/float/boolean/void/double/long/short/byte` + * 标识符判定:`[A-Za-z_][A-Za-z0-9_]*` +* **扫描器体系(FSM/模板方法)** + * 接口与基类:`TokenScanner`、`AbstractTokenScanner`(封装通用扫描/读流工具) + * 具体扫描器: + * `WhitespaceTokenScanner` —— 跳过空白(不含换行) + * `NewlineTokenScanner` —— 把 `\n` 作为 `NEWLINE` 记号 + * `CommentTokenScanner` —— `//` 单行、`/* ... */` 多行注释(FSM) + * `NumberTokenScanner` —— 十进制整数/小数,支持**单字符类型后缀**:`b/s/l/f`(大小写均可),如 `2.0f`、`255B` + * `IdentifierTokenScanner` —— 识别标识符并交由 `TokenFactory` 判定是否关键字/类型/布尔字面量 + * `StringTokenScanner` —— 双引号字符串,支持转义 `\" \\ \n \t` 等(FSM,保留原文) + * `OperatorTokenScanner` —— `= == != > >= < <= && || %` 等 + * `SymbolTokenScanner` —— `: , . + - * / ( ) [ ]` + * `UnknownTokenScanner` —— 兜底,遇到非法字符抛出 `LexicalException` +* **引擎与校验** + * `LexerEngine`:驱动扫描器链;捕获 `LexicalException`→记录为 `LexicalError`;末尾补 `EOF` + * **健壮性处理**:`skipInvalidLexeme()` 遇到 `1abc` 等错误片段时**一次性吞掉残余**,避免产生连锁误报 + * **轻量规则校验**(`validateTokens()`): + * `declare` 后必须紧跟**合法标识符**(允许可选 `const`) + * `declare` 后**禁止出现第二个多余的标识符** +* **上下文与定位** + * `LexerContext`:统一换行为 `\n`;1-based 行/列;`advance/peek/peekNext/peekAhead(n)/match(ch)`;跟踪 `lastCol` +* **错误与报告** + * `LexicalException`(抛出于扫描阶段,禁止堆栈,专注单行错误描述) + * `LexicalError`(文件/行/列/消息,统一格式:`file:///abs/path:line:col: message`) + * `LexerEngine#report(errors)`:汇总输出 +* **打印与调试** + * `TokenPrinter`:表格化打印 `line/col/type/lexeme`,对换行/制表做可视化转义;遇 `NEWLINE` 额外空行 + +## 词法细则(Token 一览) + +* **标识与关键字** + * `IDENTIFIER`:`[A-Za-z_][A-Za-z0-9_]*` + * `KEYWORD`:见上“关键字” + * `TYPE`:见上“内置类型” +* **字面量** + * `BOOL_LITERAL`:`true`/`false` + * `STRING_LITERAL`:双引号字符串,支持转义 `\" \\ \n \t` 等 + * `NUMBER_LITERAL`:十进制整数/小数,允许后缀 `b/s/l/f`(大小写) +* **符号/运算符** + * 标点/括号:`COLON(:), COMMA(,), DOT(.), LPAREN(()), RPAREN()), LBRACKET([), RBRACKET(])` + * 算术:`PLUS(+), MINUS(-), MULTIPLY(*), DIVIDE(/), MODULO(%)` + * 比较/逻辑: + `EQUALS(=), DOUBLE_EQUALS(==), NOT(!), NOT_EQUALS(!=), GREATER_THAN(>), GREATER_EQUAL(>=), LESS_THAN(<), LESS_EQUAL(<=), AND(&&), OR(||)` +* **其它** + * `NEWLINE`:换行 + * `COMMENT`:`//...` 或 `/* ... */` + * `EOF`:文件结束 + * `UNKNOWN`:无法识别的字符序列(立即报错) ## 模块结构 ``` lexer/ - ├── base/ // 公共基础接口 - ├── core/ // 词法分析核心引擎与上下文 - ├── scanners/ // 各类 Token 扫描器 - ├── token/ // Token 定义、工厂与类型 - ├── utils/ // 辅助工具(如 Token 打印) - └── doc/ // 项目文档 + ├── base/ + │ └── TokenScanner.java // 扫描器接口:canHandle/handle + │ + ├── core/ + │ ├── LexerContext.java // 字符流与位置信息;advance/peek/match/peekAhead + │ ├── LexerEngine.java // 引擎:扫描器链→Token流;错误捕获与轻量校验;getAllTokens/getErrors + │ ├── LexicalError.java // 词法错误模型(文件/行/列/消息) + │ └── LexicalException.java // 词法异常(无堆栈,单行描述) + │ + ├── scanners/ + │ ├── AbstractTokenScanner.java // 模板方法与工具:readWhile 等 + │ ├── WhitespaceTokenScanner.java// 跳过空白(非换行) + │ ├── NewlineTokenScanner.java // 识别 NEWLINE + │ ├── CommentTokenScanner.java // // 与 /* */ 注释(FSM) + │ ├── NumberTokenScanner.java // 数字/小数/后缀(FSM, 后缀集 "bslfBSLF") + │ ├── IdentifierTokenScanner.java// 标识符→交由 TokenFactory 归类 + │ ├── StringTokenScanner.java // 双引号字符串与转义(FSM,保留原文) + │ ├── OperatorTokenScanner.java // = == != > >= < <= && || % 等 + │ ├── SymbolTokenScanner.java // : , . + - * / ( ) [ ] + │ └── UnknownTokenScanner.java // 兜底:抛 LexicalException + │ + ├── token/ + │ ├── Token.java // Token(type, lexeme, raw, line, col);Token.eof(line) + │ ├── TokenFactory.java // 关键字/类型/布尔判定;create(raw,line,col) + │ └── TokenType.java // 全量 Token 枚举 + │ + └── utils/ + └── TokenPrinter.java // 调试打印:line/col/type/lexeme ``` -## 开发环境 +## 处理流程 + +1. **构造引擎**:`LexerEngine(source, sourceName)` +2. **扫描**:按扫描器链顺序尝试(空白→换行→注释→数字→标识符→字符串→运算符→符号→未知) +3. **异常转错误**:扫描器抛出的 `LexicalException` 被捕获为 `LexicalError`,并**跳过错误词素残余** +4. **补 EOF**:在 Token 流末尾追加 `EOF` +5. **轻量校验**:对 `declare` 语句做就地校验(可选 `const` + 单一标识符) +6. **可选打印**:调试模式下使用 `TokenPrinter` 输出 +7. **结果获取**:`getAllTokens()` / `getErrors()` -* JDK 24 或更高版本 -* Maven 构建管理 -* 推荐 IDE: IntelliJ IDEA +## 扩展与定制 ---- +* **新增关键字/类型**:修改 `TokenFactory` 中 `KEYWORDS/TYPES` 集合 +* **新增运算符**:在 `OperatorTokenScanner`/`SymbolTokenScanner` 中扩展 `switch` 分支 +* **数字后缀**:`NumberTokenScanner` 的 `SUFFIX_CHARS` 可按需扩展 +* **自定义校验**:在 `LexerEngine#validateTokens()` 中添加新的轻量规则 +* **新增扫描器**:继承 `AbstractTokenScanner` 并在 `LexerEngine` 的扫描器链中插入(顺序很关键,通常从“更具体/更长”到“更通用/兜底”) diff --git a/src/main/java/org/jcnc/snow/compiler/parser/doc/README.md b/src/main/java/org/jcnc/snow/compiler/parser/doc/README.md index 401b9be4b7553ba7359e48ed69150bcf86681cbb..9cc3ff3e31cb5fa17c50326ed352b8f5a5e55ded 100644 --- a/src/main/java/org/jcnc/snow/compiler/parser/doc/README.md +++ b/src/main/java/org/jcnc/snow/compiler/parser/doc/README.md @@ -1,45 +1,159 @@ # Snow Compiler - Parser 模块 -> Snow 编译器的前端模块 —— 负责将 Token 流解析为抽象语法树(AST) +> Snow 编译器的语法分析(Parser)模块 —— 负责把词法单元(Token)转换为抽象语法树(AST) ## 项目简介 -**Parser** 是 [Snow 编译器]() 项目的子模块,承担编译器前端的解析阶段任务。 -它负责将词法分析得到的 Token 流,按照 Snow 语言的语法规则,解析为标准的抽象语法树(AST)。 +**Parser** 是 Snow 编译器前端的核心模块,承担**语法解析**与**AST 构建**的职责。 +它位于词法分析(Lexer)与后续 IR/优化阶段之间,读取 `TokenStream`,以**Pratt 表达式解析**与**工厂分派的语句/顶层解析器** +为骨架,构建结构清晰、便于后续处理的 AST。 -框架使用了 Pratt 解析算法处理表达式,同时采用模块化设计,支持声明、函数、条件语句、循环语句等各类结构的解析。 +本 Parser 模块采用**可扩展的 Parselet 体系**与**工厂派发**的思路:以**AST 节点模型**为中心组织语法树,配合**统一的错误模型 +**、**可恢复的解析引擎**与**调试/序列化工具**,形成可扩展、可调试、且便于后续 IR 构建与代码生成的语法层。 ## 核心功能 -- **抽象语法树(AST)生成**: 定义丰富的 AST 节点类型 -- **表达式解析器**: 基于 Pratt 解析,支持优先级、调用、成员访问等 -- **语句解析器**: 支持 Snow 语言中的声明、控制流等 -- **模块解析器**: 处理 `import` 导入声明 -- **函数解析器**: 支持函数定义与调用 -- **灵活的解析上下文管理**: 错误处理与流式 Token 管理 -- **工具支持**: AST JSON 序列化,便于调试与前后端通信 +* **统一的 AST 模型** -## 模块结构 + * 基础抽象:`Node`、`ExpressionNode`、`StatementNode`、`NodeContext`(行/列/文件) + * 结构节点:`ModuleNode`、`StructNode`、`FunctionNode`、`ParameterNode`、`ImportNode` 等 + * 语句节点:`DeclarationNode`、`AssignmentNode`、`IfNode`、`LoopNode`、`ReturnNode`、`BreakNode`、`ContinueNode`、 + `ExpressionStatementNode` + * 表达式节点:`IdentifierNode`、`NumberLiteralNode`、`StringLiteralNode`、`BoolLiteralNode`、`ArrayLiteralNode`、 + `UnaryExpressionNode`、`BinaryExpressionNode`、`CallExpressionNode`、`IndexExpressionNode`、`MemberExpressionNode`、 + `NewExpressionNode` -``` -parser/ - ├── ast/ // AST 节点定义 - ├── base/ // 顶层解析器接口 - ├── context/ // 解析上下文与异常处理 - ├── core/ // 核心解析引擎 - ├── expression/ // 表达式解析模块 - ├── factory/ // 解析器工厂 - ├── function/ // 函数解析及 AST 打印 - ├── module/ // 模块导入解析 - ├── statement/ // 各类语句解析器 - └── utils/ // JSON 序列化、辅助方法 -``` +* **解析引擎与上下文** + + * 引擎:`ParserEngine`(驱动顶层解析;**聚合错误并可同步恢复**) + * 上下文:`ParserContext`(封装 `TokenStream` 与源信息) + * Token 读写:`TokenStream`(`peek/next/match/expect`、自动跳过评论/多余换行、提供 EOF 保护) + * 错误模型:`ParseException`(`MissingToken` / `UnexpectedToken` / `UnsupportedFeature`)与 `ParseError` DTO(统一错误收集与报告) + +* **表达式解析体系(Pratt Parser)** + + * 入口:`PrattExpressionParser`,注册**前缀/中缀 Parselet** + * 前缀:`IdentifierParselet`、`NumberLiteralParselet`、`StringLiteralParselet`、`BoolLiteralParselet`、 + `ArrayLiteralParselet`、`GroupingParselet`、`UnaryOperatorParselet`(`-`/`!`)、`NewObjectParselet` + * 中缀:`BinaryOperatorParselet`(加/减/乘/除/比较/逻辑/等于…)、`CallParselet`(函数调用)、`IndexParselet`(`[]`)、 + `MemberParselet`(`.`) + * 优先级:`Precedence`(`LOWEST`→`OR`→`AND`→`EQUALITY`→`COMPARISON`→`SUM`→`PRODUCT`→`UNARY`→`CALL`;**CALL 级别绑定最强 + **) + +* **语句解析体系** + + * 统一接口:`StatementParser` + * 工厂派发:`StatementParserFactory`(根据首关键字选择解析器;默认回退为 `ExpressionStatementParser`) + * 语句解析器: + `DeclarationStatementParser` / `Assignment`(由 `ExpressionStatementParser` 识别)/ `IfStatementParser` / + `LoopStatementParser` / `ReturnStatementParser` / `BreakStatementParser` / `ContinueStatementParser` / + `ExpressionStatementParser` + * 语句工具:`ParserUtils`(匹配区块头尾、跳过多余换行等)、`FlexibleSectionParser`(注册式**可乱序**命名小节解析器,用于 + `function/loop/struct` 等复杂体) + +* **顶层/模块/函数/结构体解析** -## 开发环境 + * 顶层接口:`TopLevelParser` + * 顶层工厂:`TopLevelParserFactory`(`module` / `function` 显式注册;其他回退到脚本模式) + * `ScriptTopLevelParser`:**脚本模式**(无 `module` 时直接解析一条顶层语句,后续由 IR 包装为 `_start`) + * `ModuleParser`:解析 `module ... end module`(含 `imports/globals/struct/function` 等子区块) + * `ImportParser`:解析 `import: a, b, c` + * `FunctionParser`:解析 `function`(`params/returns/body` 三小节,参数/返回/函数体) + * `StructParser`:解析 `struct`(字段声明、可选 `extends`、构造器 `init`、方法 `method` 等子区块) -* JDK 24 或更高版本 -* Maven 构建管理 -* 推荐 IDE: IntelliJ IDEA +* **操作符与优先级/结合性** ---- + * 二元:`+ - * / %`、比较(`< <= > >=`)、等值(`== !=`)、逻辑(`&& ||`)等,由 + `BinaryOperatorParselet(Precedence, leftAssoc)` 控制优先级与结合性 + * 一元:`-`(取负)、`!`(逻辑非),由 `UnaryOperatorParselet` 解析 + * 访问/调用:成员访问 `.`、下标 `[]`、函数调用 `()`、对象创建 `new`,均以**CALL 级优先级**绑定 +* **AST 打印与调试支持** + + * `ASTPrinter`:以缩进树形打印 AST;支持把 `Module/Struct/Function/If/Loop/Expr` 等直观输出 + * `ASTJsonSerializer`:把 AST 序列化为 `Map/List` 结构(便于测试对比、工具联动) + * `JsonFormatter` / `JSONParser`:JSON 美化与解析(测试/调试辅助) + +* **全局辅助** + + * `FlexibleSectionParser`:**注册驱动**的命名小节解析器(`condition+parser` 组合) + * `ParserUtils`:通用匹配&容错(例如跳过空行、匹配 `end xxx`) + * `TopLevelParserFactory` / `StatementParserFactory`:**集中注册点**,便于扩展语法 + +## 模块结构 + +``` +parser/ +├── ast/ // AST 节点定义 +│ ├── base/ // AST 基类:Node / ExpressionNode / StatementNode / NodeContext +│ ├── ... // 具体节点:Module / Struct / Function / Parameter / Import +│ ├── ... // 语句:Declaration / Assignment / If / Loop / Return / Break / Continue / ExprStmt +│ └── ... // 表达式:Identifier / Literals / Unary / Binary / Call / Index / Member / New / Array +│ +├── base/ +│ └── TopLevelParser.java // 顶层解析接口 +│ +├── context/ // 解析上下文与错误模型 +│ ├── ParserContext.java // 封装 TokenStream + 源信息 +│ ├── TokenStream.java // peek / next / match / expect / 跳过注释&换行 +│ ├── ParseException.java // 解析期异常基类(行/列/原因) +│ ├── ParseError.java // 错误 DTO(聚合输出) +│ ├── MissingToken.java // 必需 token 缺失 +│ ├── UnexpectedToken.java // 意外 token +│ └── UnsupportedFeature.java // 暂未支持的语法 +│ +├── core/ +│ └── ParserEngine.java // 解析引擎:驱动顶层、聚合错误、同步恢复 +│ +├── expression/ // 表达式解析(Pratt) +│ ├── base/ // ExpressionParser / PrefixParselet / InfixParselet +│ ├── PrattExpressionParser.java // Pratt 解析入口,注册所有前缀/中缀 parselet +│ ├── Precedence.java // 运算符优先级枚举 +│ ├── NumberLiteralParselet.java // 数字字面量 +│ ├── StringLiteralParselet.java // 字符串字面量 +│ ├── BoolLiteralParselet.java // 布尔字面量 +│ ├── ArrayLiteralParselet.java // 数组字面量 +│ ├── IdentifierParselet.java // 标识符 +│ ├── GroupingParselet.java // 括号分组 (...) +│ ├── UnaryOperatorParselet.java // -x / !x +│ ├── BinaryOperatorParselet.java// a+b / a\*b / 比较 / 逻辑 / 等值 +│ ├── CallParselet.java // 调用 foo(...) +│ ├── IndexParselet.java // 下标 a\[b] +│ ├── MemberParselet.java // 成员 a.b +│ └── NewObjectParselet.java // new Type(args) +│ +├── factory/ +│ ├── TopLevelParserFactory.java // 根据关键字分派:module/function;否则脚本模式 +│ └── StatementParserFactory.java// 根据关键字分派语句解析器,默认 ExprStmt +│ +├── function/ +│ ├── FunctionParser.java // function 解析:params / returns / body +│ └── ASTPrinter.java // 调试用 AST 打印器(文本/JSON) +│ +├── module/ +│ ├── ModuleParser.java // module ... end module(含 imports/globals/struct/function 子区块) +│ └── ImportParser.java // import: a, b, c +│ +├── struct/ +│ └── StructParser.java // struct 定义(字段、可选 extends、init/method 等) +│ +├── statement/ // 语句解析器 +│ ├── StatementParser.java +│ ├── DeclarationStatementParser.java +│ ├── ExpressionStatementParser.java +│ ├── IfStatementParser.java +│ ├── LoopStatementParser.java +│ ├── ReturnStatementParser.java +│ ├── BreakStatementParser.java +│ └── ContinueStatementParser.java +│ +├── top/ +│ └── ScriptTopLevelParser.java // 脚本模式(无 module) +│ +└── utils/ // 工具集 +├── ParserUtils.java // 匹配 end/跳过空行等通用操作 +├── FlexibleSectionParser.java // 注册式命名小节解析(函数/循环/结构体) +├── ASTJsonSerializer.java // AST → Map/List(便于测试/调试) +├── JsonFormatter.java // JSON 美化 +└── JSONParser.java // 简单 JSON 解析(测试/工具链) +``` diff --git a/src/main/java/org/jcnc/snow/compiler/semantic/doc/README.md b/src/main/java/org/jcnc/snow/compiler/semantic/doc/README.md index 43596744d636f7e445004dc96bb52b71c2f4c48d..baabb819f33df410f9abc4fcb19f8d7c72212afd 100644 --- a/src/main/java/org/jcnc/snow/compiler/semantic/doc/README.md +++ b/src/main/java/org/jcnc/snow/compiler/semantic/doc/README.md @@ -1,41 +1,155 @@ -# Snow Compiler - Semantic 模块 +# Snow Compiler - 语义分析(Semantic)模块 -> Snow 编译器的前端模块 —— 负责语义分析与符号表管理 +> Snow 编译器的语义分析层 —— 负责 **AST** 的类型检查、符号/模块/函数签名管理与语义错误收集 ## 项目简介 -**Semantic** 是 [Snow 编译器]() 项目的子模块,承担编译器前端的语义分析阶段任务。 -它负责在抽象语法树(AST)基础上,进行符号绑定、类型检查、作用域管理等操作,确保程序符合语义规则,并为后续中间代码生成(IR)阶段提供准备。 +**语义分析(Semantic Analysis)** 是 Snow 编译器在语法之后、IR 之前的关键阶段。 +该模块在遍历 AST 的同时,完成**类型推断与检查**、**符号与作用域解析**、**模块/结构体/函数签名登记**、以及**错误汇总与报告**,为后续 IR 生成与优化提供可靠、结构化的类型与符号信息。 -该模块采用模块化设计,针对不同类型的表达式与语句提供独立的分析器,同时内置完整的符号表和类型系统支持。 +语义层采用“**注册表 + 访问器接口 + 分析器实现**”的可插拔设计:以 `AnalyzerRegistry` 为分发中心、`ExpressionAnalyzer`/`StatementAnalyzer` 为契约、配套 **模块/函数签名三阶段流程** 与 **类型系统**,形成清晰、易扩展、便于调试的语义分析框架。 ## 核心功能 -- **表达式与语句语义分析**: 根据 Snow 语言规范校验各类 AST 节点 -- **符号表管理**: 支持作用域嵌套、符号绑定与查找 -- **类型系统**: 内建基础类型与函数类型推导 -- **语义错误报告**: 标准化错误收集与输出 -- **可扩展的分析器体系**: 按节点类型组织,便于维护与扩展 +* **顶层调度与三阶段流程** + + * `SemanticAnalyzer`:语义分析总控,按阶段运行 + + 1. **模块注册** `ModuleRegistry#registerUserModules` + 2. **签名登记** `SignatureRegistrar#register`(函数/方法/构造函数) + 3. **函数体检查** `FunctionChecker#check` + * `SemanticAnalyzerRunner`:对外统一入口(从 AST 过滤 `ModuleNode`,执行语义并输出报告) + +* **分析器体系(可插拔)** + + * 注册中心:`AnalyzerRegistry`(基于 AST 节点类型分发到对应分析器,含兜底 `UnsupportedExpressionAnalyzer`) + * 基础契约:`ExpressionAnalyzer`、`StatementAnalyzer` + * 注册器:`AnalyzerRegistrar`(一次性注册全部语句/表达式分析器) + +* **表达式分析器(部分列举)** + + * 字面量:`NumberLiteralAnalyzer`、`StringLiteralAnalyzer`、`BoolLiteralAnalyzer`、`ArrayLiteralAnalyzer` + * 变量与成员:`IdentifierAnalyzer`、`MemberExpressionAnalyzer`(支持 `模块.成员` 与 `结构体.字段/方法`) + * 计算与取值:`BinaryExpressionAnalyzer`、`UnaryExpressionAnalyzer`、`IndexExpressionAnalyzer` + * 调用与构造:`CallExpressionAnalyzer`(支持 模块.函数 / 结构体方法 / 普通函数)、`NewExpressionAnalyzer` + * 兜底:`UnsupportedExpressionAnalyzer` + +* **语句分析器(部分列举)** + + * 声明与赋值:`DeclarationAnalyzer`、`AssignmentAnalyzer`、`IndexAssignmentAnalyzer` + * 控制流:`IfAnalyzer`、`LoopAnalyzer`、`ReturnAnalyzer`、`BreakAnalyzer`、`ContinueAnalyzer` + * 表达式语句:对 `ExpressionStatementNode` 直接转发到表达式分析器 + +* **符号与作用域模型** + + * `Symbol` / `SymbolKind` / `SymbolTable`(链式父子作用域;`resolve` 向上查找;`define` 当前层定义) + * `ModuleInfo`:每个模块的元信息(**imports**、**functions**、**structs**、**globals**) + * `ModuleRegistry`:将用户模块写入全局上下文以供跨模块解析 + +* **类型系统与类型提升** + + * 核心接口:`Type`(`isCompatible`/`isNumeric`/`name`/`widen`) + * 具体类型:`BuiltinType`(byte/short/int/long/float/double/string/boolean/void)、`ArrayType`、`FunctionType`、`StructType` + * 内建注册:`BuiltinTypeRegistry`(注册所有内置基本类型;示例内置模块 `os` 及函数 `syscall(string,int):void`) + * 类型解析:`Context#parseType` 支持 **多维数组**(如 `int[][]`)、**结构体类型**(`模块.结构体`) + * 数值宽化:在声明/赋值/调用/构造场景支持 **数值类型自动宽化**(`Type.widen`) + +* **模块/结构体/函数签名登记** + + * `SignatureRegistrar`:遍历模块,登记**结构体**(字段/方法/父类)、**自由函数**、**构造函数**的 `FunctionType` + * 跨模块访问:`MemberExpressionAnalyzer`/`CallExpressionAnalyzer` 结合 `ModuleInfo#imports` 做**导入校验** + +* **常见语义规则(内置检查)** + + * **If/Loop 条件**:必须为 `boolean`(`TypeUtils.isLogic` 定义的逻辑约束) + * **声明初始化/赋值**:类型**兼容或可宽化**,否则报错 + * **返回语句**:返回值与函数签名一致;**非 void 函数**必须至少出现一条 `return` + * **数组**:字面量元素类型需一致;`arr[index]` 的 `index` 必须是**数值类型**;下标赋值需与元素类型一致 + * **成员与调用解析**:支持 + `变量.字段`/`变量.方法`(结构体实例) + `模块.常量/变量/函数`(需导入或同模块) + 普通函数名解析(当前作用域/模块) + +* **错误报告与调试** + + * `SemanticError`:携带源位置信息(文件/行/列),友好 `toString` 文本 + * `SemanticAnalysisReporter`:统一汇总打印;可配置**仅打印**或**打印并退出** + * `Context#log(boolean verbose)`:按需输出细粒度调试日志 ## 模块结构 ``` semantic/ - ├── analyzers/ // 各类表达式和语句分析器 - │ ├── base/ // 基础分析器接口 - │ ├── expression/ // 表达式分析器 - │ └── statement/ // 语句分析器 - ├── core/ // 核心分析引擎与上下文管理 - ├── error/ // 语义错误定义 - ├── symbol/ // 符号表系统 - ├── type/ // 类型系统 - └── utils/ // 辅助工具 + ├── analyzers/ // 语义分析器体系:注册与分发 + │ ├── AnalyzerRegistry.java // AST 节点类型 -> 分析器 实例映射(含兜底) + │ ├── TypeUtils.java // 语义层类型工具(逻辑/布尔判定等) + │ ├── base/ + │ │ ├── ExpressionAnalyzer.java // 表达式分析器接口 + │ │ └── StatementAnalyzer.java // 语句分析器接口 + │ ├── expression/ // 各类表达式分析器 + │ │ ├── NumberLiteralAnalyzer.java + │ │ ├── StringLiteralAnalyzer.java + │ │ ├── BoolLiteralAnalyzer.java + │ │ ├── IdentifierAnalyzer.java + │ │ ├── BinaryExpressionAnalyzer.java + │ │ ├── UnaryExpressionAnalyzer.java + │ │ ├── ArrayLiteralAnalyzer.java + │ │ ├── IndexExpressionAnalyzer.java + │ │ ├── MemberExpressionAnalyzer.java + │ │ ├── CallExpressionAnalyzer.java + │ │ ├── NewExpressionAnalyzer.java + │ │ └── UnsupportedExpressionAnalyzer.java + │ └── statement/ // 各类语句分析器 + │ ├── DeclarationAnalyzer.java + │ ├── AssignmentAnalyzer.java + │ ├── IndexAssignmentAnalyzer.java + │ ├── IfAnalyzer.java + │ ├── LoopAnalyzer.java + │ ├── ReturnAnalyzer.java + │ ├── BreakAnalyzer.java + │ └── ContinueAnalyzer.java + │ + ├── core/ // 顶层流程与全局上下文 + │ ├── SemanticAnalyzerRunner.java // 语义分析入口:筛选模块节点并运行 + │ ├── SemanticAnalyzer.java // 三阶段总控(注册模块/登记签名/函数检查) + │ ├── Context.java // 全局上下文:模块表、错误表、日志、类型解析 + │ ├── ModuleRegistry.java // 模块注册(写入 Context#modules) + │ ├── SignatureRegistrar.java // 函数/方法/构造签名登记 + │ ├── FunctionChecker.java // 函数体遍历与作用域/return 检查 + │ ├── ModuleInfo.java // 模块元信息(imports/functions/structs/globals) + │ ├── BuiltinTypeRegistry.java // 内置类型/内置模块与函数(如 os.syscall) + │ └── AnalyzerRegistrar.java // 将全部分析器注册进 AnalyzerRegistry + │ + ├── symbol/ + │ ├── Symbol.java // 符号项(name/type/kind) + │ ├── SymbolKind.java // 符号分类(VARIABLE/CONSTANT/FUNCTION/MODULE) + │ └── SymbolTable.java // 链式作用域:define/resolve + │ + ├── type/ + │ ├── Type.java // 类型接口 + 辅助(isCompatible/isNumeric/widen/name) + │ ├── BuiltinType.java // 内置基础类型(整型/浮点/字符串/布尔/void) + │ ├── ArrayType.java // 数组类型(支持多维) + │ ├── FunctionType.java // 函数类型(参数列表 + 返回类型) + │ └── StructType.java // 结构体类型(字段/方法/父类/成员解析) + │ + ├── error/ + │ └── SemanticError.java // 语义错误模型(含源位置) + │ + └── utils/ + └── SemanticAnalysisReporter.java // 错误汇总打印与退出策略 ``` -## 开发环境 +## 设计要点 + +* **阶段化**:将“全局签名收集”和“函数体检查”解耦,避免前向引用/跨模块依赖导致的顺序问题。 +* **作用域安全**:`SymbolTable` 通过父指针实现块级/函数级/模块级多层作用域;`If`/`Loop` 分支各自使用独立作用域。 +* **解析顺序**:成员与调用遵循“先模块、后结构体、再本地符号”的解析策略,结合 `imports` 做跨模块访问控制。 +* **类型宽化**:对数值类型在声明/赋值/调用/构造时按 `Type.widen` 进行安全宽化;字符串调用形参支持从数值到 string 的隐式接收(见 `CallExpressionAnalyzer`)。 + +## 扩展 -* JDK 24 或更高版本 -* Maven 构建管理 -* 推荐 IDE: IntelliJ IDEA +新增语法节点仅需 ---- \ No newline at end of file + 1. 实现对应 `ExpressionAnalyzer`/`StatementAnalyzer`, + 2. 在 `AnalyzerRegistrar#registerAll` 中注册, + 3. 必要时在 `SignatureRegistrar` 扩展签名收集逻辑。 \ No newline at end of file diff --git a/src/main/java/org/jcnc/snow/vm/doc/README.md b/src/main/java/org/jcnc/snow/vm/doc/README.md new file mode 100644 index 0000000000000000000000000000000000000000..e92f4f3756c3365775d283f768ac4c8f56fe6a90 --- /dev/null +++ b/src/main/java/org/jcnc/snow/vm/doc/README.md @@ -0,0 +1,118 @@ +# Snow VM - 虚拟机(指令集 & 执行引擎)模块 + +> Snow 运行时的栈式虚拟机 —— 负责**装载文本指令**、**解释执行**、并提供**类型化算术/比较、控制流、系统调用与 I/O**等能力 + +## 项目简介 + +本模块实现了 Snow 的**指令集虚拟机(VM)**,用于运行由编译器/汇编器生成的“文本化指令序列”。 +它采用**命令(Command)模式 + 统一操作码表(`VMOpCode`)+ 工厂注册(`CommandFactory`)**的结构,配合**运行时栈/局部变量表/调用栈**与**方法栈帧**,构成清晰可扩展的执行层。 + +执行流程:`VMLauncher/VMInitializer` 解析指令文件 → `CommandLoader` 读入并清洗文本 → `VirtualMachineEngine` 主循环按 **PC** 逐条解释执行(跳过空行与 `#` 注释),通过 `CommandExecutionHandler` 分发到各具体指令类,直到 `RET`(根帧)或 `HALT` 正常终止。 + +## 核心功能 + +* **统一的指令与分发模型** + * 抽象接口:`interfaces.Command#execute(String[] parts, int pc, OperandStack, LocalVariableStore, CallStack)` + * 操作码表:`engine.VMOpCode`(以 `int` 编码,分段保留:**0x0000–0x00DF 类型算术/比较/装载**、**0x00E0–0x00E2 引用操作**、**0x0100– 栈操作**、**0x0200– 流程控制**、**0x0300– 寄存器移动**、**0x0400– 系统**) + * 指令工厂:`factories.CommandFactory` 将 `opCode → Command` 静态注册,`CommandExecutionHandler#handle` 统一查表并调用 + +* **执行引擎与运行时** + * 引擎主循环:`engine.VirtualMachineEngine` + * 维护 **PC**、`OperandStack`(操作数栈)、`LocalVariableStore`(局部变量表)、`CallStack`(调用栈) + * **根栈帧**:首次执行前 `ensureRootFrame()` 推入;`RET` 在根帧返回 **PROGRAM_END**(`Integer.MAX_VALUE`)以优雅终止 + * 解析规则:每行第一段为**十进制操作码**,后续为操作数;空行与以 `#` 开头的行被忽略 + * 调度与容错:`execution.CommandExecutionHandler` 进行指令分发,捕获异常并保证 VM 安全退出 + * 执行器外壳:`engine.VMCommandExecutor` 封装运行与日志 + +* **类型化指令族(算术/比较/装载)** + * **整数/定长**:`byte8`(B\*)、`short16`(S\*)、`int32`(I\*)、`long64`(L\*) + * 典型操作:`ADD/SUB/MUL/DIV/MOD/NEG/INC`、按位 `AND/OR/XOR`、`PUSH/LOAD/STORE`、比较 `CE/CNE/CG/CGE/CL/CLE` + * 对应类示例:`IAddCommand`、`LAndCommand`、`BStoreCommand`、`SCECommand`… + * **浮点**:`float32`(F\*)、`double64`(D\*) + * 典型操作:`ADD/SUB/MUL/DIV/MOD/NEG/INC`、`PUSH/LOAD/STORE`、比较(无按位操作) + * 对应类示例:`FAddCommand`、`DSubCommand`、`FLoadCommand`、`DCGECommand`… + * **类型转换**:`type/conversion` 下提供 **全组合**数值转换(如 `I2L/F2D/D2I/B2S` 等),一律通过 `VMOpCode` 明确定义 + +* **控制流与调用** + * **无条件跳转**:`JumpCommand`(`JUMP`) + * **调用/返回**:`CallCommand`(`CALL`,从栈按**左到右**顺序取实参,建立新 `StackFrame` 并设置返回地址),`RetCommand`(`RET`,弹栈帧并回到调用点;根帧返回触发终止) + * **栈操作**:`PopCommand`(`POP`)、`DupCommand`(`DUP`)、`SwapCommand`(`SWAP`) + * **寄存器移动**:`MovCommand`(`MOV src,dst`,在同一局部变量表内复制槽位) + +* **引用/对象与虚方法支持** + * 引用操作:`R_PUSH / R_LOAD / R_STORE`(分别用于将引用压栈、从局部变量表加载/存储引用) + * 运行时模型: + * `module.StackFrame`(保存返回地址、`LocalVariableStore`、`OperandStack`、`MethodContext`) + * `module.CallStack`(带上限保护的调用栈) + * `module.Instance`、`module.VirtualTable`(vtable:方法签名 → 入口地址,支持动态分派) + +* **系统调用与 I/O** + * 统一入口:`SyscallCommand`(`SYSCALL`),失败时约定**向栈压 `-1`** + * 文件/网络/控制台子命令(示例):`PRINT/PRINTLN`、`OPEN/CLOSE/READ/WRITE/SEEK`、`PIPE/DUP`、`SOCKET/CONNECT/BIND/LISTEN/ACCEPT`、`SELECT`,以及**数组访问** `ARR_GET/ARR_SET` + * 文件描述符表:`io.FDTable` 维护 **虚拟 fd → NIO Channel** 映射(内置 `0:stdin / 1:stdout / 2:stderr`) + * 路径与装载:`io.FilePathResolver`、`io.FileIOUtils` 负责解析参数、读取文本并**去注释/去空行** + +* **调试与可视化** + * 日志工具:`utils.LoggingUtils` + * 状态输出:`utils.VMUtils#printVMState`、`utils.VMStateLogger` + * 变量观察:`module.LocalVariableStore#handleMode()` 在 `DEBUG` 模式下(且非 GraalVM native-image)弹出 Swing 面板查看局部变量表 + * 运行入口:`VMLauncher` / `VMInitializer`(示例流程:解析文件 → 载入指令 → 运行 → 打印 VM 状态) + +## 模块结构 + +``` +vm/ + ├── VMLauncher.java // 入口壳:解析参数,启动 VM + ├── VMInitializer.java // 启动流程:读文件 → 执行 → 打印状态 + │ + ├── engine/ // 执行引擎与操作码 + │ ├── VirtualMachineEngine // 主循环:维护 PC / 栈 / 局部表 / 调用栈 + │ ├── VMCommandExecutor // 执行器外壳与异常处理 + │ └── VMOpCode // 统一操作码定义(按功能分段编码) + │ + ├── execution/ // 指令装载与分发 + │ ├── CommandLoader // 从文件读取文本指令(去注释/空行) + │ └── CommandExecutionHandler // 查表分发并执行 Command + │ + ├── factories/ + │ └── CommandFactory // 静态注册:opCode → 指令实例 + │ + ├── interfaces/ + │ └── Command // 指令统一接口:execute(...) + │ + ├── commands/ // 具体指令实现(Command 模式) + │ ├── flow/control/ // 控制流:JUMP / CALL / RET + │ ├── stack/control/ // 栈:POP / DUP / SWAP + │ ├── register/control/ // 局部槽位移动:MOV + │ ├── system/control/ // 系统调用/终止:HALT / SYSCALL + │ ├── ref/control/ // 引用:R_PUSH / R_LOAD / R_STORE + │ └── type/ // 类型化算术/比较/装载与转换 + │ ├── control/ + │ │ ├── byte8/ // B_*:8 位有符号整数 + │ │ ├── short16/ // S_*:16 位有符号整数 + │ │ ├── int32/ // I_*:32 位有符号整数 + │ │ ├── long64/ // L_*:64 位有符号整数 + │ │ ├── float32/ // F_*:32 位浮点 + │ │ └── double64/ // D_*:64 位浮点 + │ └── conversion/ // 跨类型转换:X2Y(如 I2L、F2D 等) + │ + ├── module/ // 运行时数据结构 + │ ├── OperandStack // 操作数栈 + │ ├── LocalVariableStore // 局部变量表(自动扩容/紧凑化) + │ ├── CallStack // 调用栈(含深度保护) + │ ├── StackFrame // 栈帧:返回地址 + 局部表 + 栈 + 方法元信息 + │ ├── MethodContext // 方法上下文(名称/实参,用于调试) + │ ├── Instance // 对象实例占位 + │ └── VirtualTable // vtable:方法签名 → 入口地址 + │ + ├── io/ // I/O 与文件系统桥接 + │ ├── FDTable // 虚拟 fd ↔ NIO Channel 映射(含 0/1/2) + │ ├── FileIOUtils // 读取并清洗指令文本 + │ └── FilePathResolver // 解析指令文件路径 + │ + └── utils/ // 通用工具与调试 + ├── LoggingUtils // 统一日志 + ├── VMUtils // 打印 VM 状态等 + └── VMStateLogger // 状态日志封装 +``` +