Metadata-Version: 2.4
Name: jzcheck
Version: 0.7.0
Summary: JZ Assembly Static Checker
Author: jzcheck contributors
License-Expression: MIT
Classifier: Development Status :: 3 - Alpha
Classifier: Environment :: Console
Classifier: Programming Language :: Python :: 3
Classifier: Topic :: Software Development :: Assemblers
Requires-Python: >=3.12
Description-Content-Type: text/markdown
Requires-Dist: pygls<3.0,>=2.0

# jzcheck

JZ Assembly Static Checker — JZ8 系列 OTP 微控制器汇编静态分析工具。

提供 **CLI 链接器**（基于 `.mpj` 项目文件的完整检查）、**LSP 服务器**（VS Code IDE 集成）、**代码格式化器** 三大功能。

## 安装

### 从源码安装

```bash
pip install .
```

### 从 .whl 文件安装

先打包生成 `.whl` 文件：

```bash
# 安装构建工具
pip install build

# 构建 wheel 包（产物在 dist/ 目录下）
python -m build --wheel .
```

或使用项目根目录下的打包脚本（自动清理旧产物）：

```batch
# Windows
build_jzcheck.bat
```

安装 `.whl` 文件：

```bash
pip install dist\jzcheck-0.1.0-py3-none-any.whl
```

也可将 `.whl` 拷贝到其他机器离线安装：

```bash
pip install jzcheck-0.1.0-py3-none-any.whl
```

卸载：

```bash
pip uninstall jzcheck
```

### 开发模式安装（源码修改即时生效）

```bash
pip install -e .
```

## 快速开始

```bash
# 检查项目文件（仅支持 .mpj 模式，不支持独立 .asm）
jzcheck project.mpj

# 指定芯片 XML 配置目录
jzcheck -x config/ project.mpj

# 静默模式（只显示 error 和 warning）
jzcheck -q project.mpj

# 警告视为错误
jzcheck -w project.mpj

# 显示详细堆栈分析
jzcheck --stack-detail project.mpj
```

## 命令行参数

| 参数 | 说明 |
|------|------|
| `mpj` | `.mpj` 项目文件（必填） |
| `-x` / `--xml-dir` | 芯片 XML 配置目录（默认使用内置 config/） |
| `-q` / `--quiet` | 静默模式，抑制 info 级别消息 |
| `-w` / `--warnings-as-errors` | 将警告视为错误 |
| `--stack-detail` | 显示详细堆栈分析路径信息 |
| `--version` | 显示版本号 |

## LSP 服务器

```bash
jzcheck-lsp
```

使用 `pygls` 协议，配合 VS Code 扩展提供 IDE 特性：

| 特性 | 说明 |
|------|------|
| 诊断 | 打开/编辑时实时推送词法、语法、语义、内存诊断 |
| 代码补全 | 指令、寄存器、符号、位索引补全 |
| 悬停信息 | 指令文档、符号定义、宏展开、寄存器位字段 |
| 跳转到定义 | 符号、宏、寄存器的定义位置 |
| 文档符号 | 标签 + EQU 常量的大纲视图 |
| CodeLens | 函数上方显示静态堆栈深度 |
| 代码格式化 | 规范化缩进、大小写、对齐 |
| 符号重命名 | 跨文件标签、EQU 常量、宏名重命名 |

## 诊断代码

| 代码 | 级别 | 含义 |
|------|------|------|
| E001 | 错误 | 词法错误（无效字符、无效十六进制、无效立即数） |
| E002 | 错误 | 语法错误（未知指令、意外的行首标记） |
| E003 | 错误 | 操作数不匹配 |
| E005 | 错误 | 未定义符号 |
| E006 | 错误 | 重复符号/标签 |
| E011 | 错误 | 宏展开深度超过限制（100 层） |
| E013 | 错误 | 跳转目标超出 ROM 范围 |
| E015 | 错误 | 程序超出 ROM 大小 |
| E016 | 错误 | CALL/JMP 到未定义标签/函数 |
| E999 | 错误 | 内部分析错误 |
| W001 | 警告 | 标识符超过 32 个字符 |
| W003 | 警告 | 宏参数数量不匹配 |
| W005 | 警告 | 堆栈深度达到/超过芯片限制 |
| W007 | 警告 | 递归调用检测 |
| W009 | 警告 | ISR 嵌套风险（中断内启用 EI） |
| W010 | 警告 | 主程序 + 中断组合超过堆栈限制 |
| W011 | 警告 | 函数缺少 RET/RETI/RETL |
| W012 | 警告 | CALL/RET 不平衡 |
| W013 | 警告 | 函数内混合返回类型 |
| W014 | 警告 | ORG 区域重叠 |
| I002 | 信息 | 孤立函数（已定义但从未调用） |
| I003 | 信息 | 流水线进度消息 |

## 检查内容

### 词法/语法检查
- 非法字符检测（含编码自动检测 UTF-8/GBK）
- 助记符拼写错误（68 个名称 / 43 个基础助记符 + 24 个 EM78P153 别名 + INT，81 种操作数模式）
- 操作数数量/格式/模式匹配验证
- 数值格式错误（如 `0xGG`）
- 标签名合法性、标识符长度限制（32 字符）
- 三种注释风格：`//`、`;`、`/* */`

### 宏处理
- MACRO/ENDM 定义解析，支持参数、嵌套、LOCAL、EXITM
- 参数替换展开（大小写不敏感匹配）
- 嵌套宏递归展开，深度上限保护（100 层）
- 重复宏定义检测、参数数量验证
- 条件指令：`IF`/`ELSE`/`ENDIF`、`IFB`/`IFNB`/`IFDEF`/`IFNDEF`/`IFIDNI`/`IFDIFI`/`ELSEIF`
- 重复块：`REPT`、`FOR`、`FORC`
- 运行时指令：`ERROR`、`ECHO`、`VARARG`、`EXPAND`

### 语义检查（2-pass 分析）
- **第 1 遍**：构建符号表（标签 + EQU 定义）
- **第 2 遍**：交叉引用检查、寻址模式验证
- 未定义符号检测、重复定义检测
- ORG 地址跟踪、EQU 表达式求值（支持十六进制/二进制/符号引用/`$` PC）
- 位操作符号解析（`REG.BIT` 链式追踪）
- 跳转/调用目标范围验证（`$+N`/`$-N`）
- EM78P153 兼容别名（24 个）支持

### 内存检查
- ROM 越界检查（基于芯片配置）
- RAM 分配范围检查（用户 RAM vs 专用寄存器）
- RAM 地址重叠检测、ORG 区域重叠检测
- 用户 RAM 与专用寄存器冲突检查
- 寄存器地址冲突检查

### 堆栈静态分析（5 阶段）
1. **函数构建 + 调用图**：按标签分割函数，提取调用关系
2. **调用图遍历**：路径敏感 DFS 深度计算，循环/递归检测
3. **中断分析**：ISR 检测、嵌套风险分析
4. **泄漏检测**：缺失 RET、CALL/RET 平衡、混合返回类型
5. **综合报告**：主程序 + 中断组合深度、最差路径

### 代码格式化
- 幂等格式化（`format(format(x)) == format(x)`）
- 规范化缩进、指令大小写、寄存器大小写、十六进制大小写
- 四列对齐（标签/指令/操作数/注释）
- 对注释无损（含 `/* */` 块注释）

## 支持的芯片

内置 40 种 JZ8 系列芯片配置（位于 `jzcheck/config/`），包括：

| 系列 | 型号 |
|------|------|
| JZ8F | 8003, 8620, FT4801, FT8801 |
| JZ8M | 1602, 2532, 2605, 2632, 4600, 4601 |
| JZ8P | 0510, 1503S, 1507, 1510, 1520, 1521, 1525, 153, 1530, 1531, 155, 1611, 2506, 2508, 2521, 2600, 2610, 2612, 2613, 2615, 2616, 5308, 5318, E155E, E255E |
| JZ8PT | 2500, 2503 |
| JZSP | 4001, 4002, 8001 |

默认芯片：**JZ8P1520**（14 位指令宽度，1024 字节 ROM，80 字节 RAM，5 级堆栈）

## 支持的语法

- **注释**：`//`、`;`、`/* ... */`
- **立即数**：`@` 前缀（如 `@0xff`、`@30`、`@TCC_NUM`）
- **数值**：十六进制 `0x`/`0X`、二进制 `0b`、十进制
- **位寻址**：`REG.BIT` 语法（如 `FLAG_FUCTION_0.0`、`STATUS.7`）
- **相对寻址**：`$`、`$+N`、`$-N`
- **伪指令**：`EQU`、`ORG`、`INCLUDE`
- **宏**：`MACRO`/`ENDM`、`LOCAL`、`EXITM`、`VARARG`、`EXPAND`
- **条件**：`IF`/`ELSE`/`ENDIF`、`IFB`、`IFNB`、`IFDEF`、`IFNDEF`、`IFIDNI`、`IFDIFI`、`ELSEIF`
- **重复**：`REPT`、`FOR`、`FORC`
- **运行时**：`ERROR`、`ECHO`
- **指令集**：43 个基础助记符 + 24 个 EM78P153 兼容别名 + `INT` = 68 个可识别的名称，共 81 种操作数模式变体

## 架构

```
jzcheck/
├── cli.py               # CLI 入口 + 流水线编排（.mpj 解析 → 检查）
├── lexer.py              # 词法分析器（编码检测 + Tokenizer）
├── parser.py             # 语法解析器 + EQU 表达式求值器 + .mpj 解析
├── macro.py              # 宏处理器（定义收集 + 参数展开 + 条件指令）
├── semantics.py          # 语义分析器（2-pass 符号表 + 寻址检查）
├── memory.py             # 内存分配检查器（ROM/RAM/ORG）
├── stack.py              # 堆栈深度静态分析器（5 阶段）
├── instructions.py       # JZ 指令集数据库（43 助记符 / 81 模式）
├── chipdb.py             # 芯片配置数据库（XML 解析 + 查询）
├── reporter.py           # 诊断报告引擎（三级 + 定位 + 退出码）
├── includer.py           # INCLUDE 路径解析器
├── formatter.py          # 代码格式化器（幂等规范化）
├── lsp_server.py         # LSP 服务器入口（pygls）
├── lsp_project.py        # LSP 工作区管理器（多文件符号管理）
│
├── config/               # 40 种芯片 XML 配置文件
│   ├── JZ8P1520.XML      # 默认芯片
│   └── *.XML
│
└── lsp_features/         # LSP 功能模块
    ├── diagnostics.py    # 诊断适配器 + 分析缓存
    ├── completion.py     # 代码补全提供者
    ├── hover.py          # 悬停信息提供者
    ├── definition.py     # 跳转到定义提供者
    ├── symbols.py        # 文档符号提供者
    ├── codelens.py       # CodeLens（堆栈深度显示）
    └── rename.py         # 符号重命名提供者
```

## 数据流

```
.mpj 项目文件
  │
  ├── parser.parse_mpj()        → 芯片型号、源文件列表、头文件列表
  ├── chipdb.load_chip()        → 芯片配置（ROM/RAM/寄存器）
  │
  ├── [头文件预处理 - 共享 MacroProcessor + SemanticAnalyzer]
  │    ├── lexer.tokenize_source()    → Token 流
  │    ├── macro.collect_definitions() → 提取宏定义
  │    ├── macro.expand_all()         → 展开宏调用
  │    ├── parser.parse_lines()       → ParsedLine 列表
  │    └── semantics.build_symbol_table()  → 符号表
  │
  ├── [源文件处理 - 第 1 遍]
  │    └── semantics.build_symbol_table()  → 收集标签
  │
  ├── [源文件处理 - 第 2 遍]
  │    ├── semantics.check_references()    → 交叉引用验证
  │    ├── memory.check_program()          → 内存分配检查
  │    └── stack.StackAnalyzer.analyze()   → 5 阶段堆栈分析
  │
  └── reporter.flush()            → 排序输出诊断 + 退出码
```

## 测试

```bash
# 运行全部测试（18 个测试文件）
python -m pytest tests/ -v

# 按模块运行
python -m pytest tests/test_lexer.py -v
python -m pytest tests/test_parser.py -v
python -m pytest tests/test_stack.py -v
python -m pytest tests/test_pipeline.py -v
```

测试覆盖：词法分析、语法解析、宏处理、语义分析、内存检查、堆栈分析、格式化、诊断适配、CodeLens、重命名、端到端流水线。

## 已知限制

- 位表达式符号（如 `BIT_TCC EQU FLAG_FUCTION_0.0`）需要符号表解析才能正确验证位操作指令
- 多文件项目模式下跨文件符号引用需要后续增强
- SONIX 兼容宏库（macro1-3.ash）暂不支持
- 仅支持 `.mpj` 项目模式，不支持独立的 `.asm` 文件检查

## 许可证

MIT
