基石jishi

基石 · 自述

一门中文编程语言,对标 Python 的易用性。北极星是方便地实现意图与出问题能快速定位——后者靠报错、调用栈和调试器三件东西兜住。

当前版本
0.2.6
测试用例
3839 项全绿
能力探针
42/50 可用**,缺口 8 项全部已判定;`python tools/probe_capabilities.py` 可复跑);**语法面自 M36(2026-09-14)起冻结**,新增语法要走准入三关。 > 📚 **历次交付的明细不写在这里**:逐里程碑(0.1.x 的 M0–M45、0.2.x 的 M46–M56 > 与 R 线的每一步)都在 [`docs/版本历史/`](docs/版本历史/);逐版本改了什么看 > [`CHANGELOG.md`](CHANGELOG.md)。README 只讲**现在**。 ## 已经能做什么 - **语法**:变量、算术/比较/逻辑、链式比较(`60 < 分数 <= 90`)、 如果/否则如果/否则、遍历、循环 N 次、当、中断/继续、函数、导入、列表/字典 - **表达力(M7)**:多赋值解包(`令 a, b = [1, 2]`、`a, b = b, a`)、 默认参数(`函数 f(a, b = 10)`)、列表/字典推导式 (`[x*2 遍历 x 在 列表 如果 x>2]`)、文本插值(`` `你好 {名字},今年 {年龄} 岁` ``) - **异常处理(M5a)**:`尝试`/`捕获 类型 为 e`/`最终`/`抛出 值`; 9 种内建错误类型(`值错误` 等)可抛可抓,基类抓子类,`e.消息`/`e.类型` 可读 - **面向对象(M5b)**:`类` 定义方法、`继承` 复用与覆盖、`新建` 实例化、 自动构造(`初始化`)、实例字段、绑定方法(`自身`) - **内建函数**:打印、输入、整数/小数/文本、精确、**序数/字符**、长度、范围、 最大、最小、总和、类型、反转、打开 - **对象方法**: - 列表:追加 / 插入 / 移除 / 弹出 / 排序 / 反转 / 清空 / 索引 / 计数 / 包含 / 映射 / 过滤 / 排序按 / 归约 - 字典:获取 / 键 / 值 / 包含 / 更新 / 弹出 / 清空 - 文本:拆分 / 替换 / 查找 / 大写 / 小写 / 去空白 / 开头是 / 结尾是 / 包含 / 转整数 / 转小数 - 集合:添加 / 移除 / 丢弃 / 包含 / 并集 / 交集 / 差集 / 对称差 / 清空 / 转列表 / 复制 - 文件:读 / 读行 / 读所有行 / 写 / 写行 / 关闭 / 刷新 / 位置 / 定位 - 精确小数:舍入 / 绝对值 / 转文本 - **语言功能(M23–M34)**:成员测试 `在`/`不在`、同一性 `是`/`不是`、 `超()` 调父类方法、类变量、`断言`、`是实例`; 集合(有序去重 + 交并差)、迭代协议、切片赋值、可选类型标注、 匿名函数、数据流水线(映射/过滤/排序按/归约); 变长参数 `*参数`/`**选项`、星号解包 `令 甲, *余 = …`; 上下文管理器 `用 … 为`、文件对象(`打开`)、自定义对象打印(`文本()` 方法)、 精确小数 `精确(…)`、**字节**(M113:真正的二进制类型,`编码.十六进制解码` / `文件.读字节` 造出来;**故意没有字面量**,所以语法面与字节码格式一处没动); **值的显示统一**(空/真/假 中文;打印·文本·插值·REPL 回显一处实现); **模式匹配** `匹配`/`情形`(单值·多值·守卫·兜底,待匹配值只求值一次)、 **枚举** `枚举`(成员是实例,可取 `.名字`/`.值`、`==` 按身份、`X.全部` 可遍历) - **中文报错**:精确到行列 + "你是不是想写…"修正建议(错误快照护航) - **REPL**:表达式回显、多行块输入、帮助/清空命令 - **开发者工具(M21 + M42 + M43)**: - `jishi lsp` 语言服务器:实时诊断 / 补全 / 悬停文档 / 跳转定义 / 文档符号; **增量同步**(只重算改动行之后的分词,大文件不再卡); **M42 补六项**:格式化 / 重命名 / 快速修复 / 签名提示 / 工作区符号 / 语义高亮;配 `editors/vscode-jishi` 语言客户端(零依赖) - `jishi dap` 调试适配器:断点 / 单步(单步·下一步·跳出)/ **变量(可点调用栈 的任意一帧看)** / 调用栈 / 监视与悬停求值 / 调试控制台;三个执行器行为一致 - `jishi 格式化`:统一缩进与间距,保留注释与字符串原样,幂等且语义不变; 支持整个目录(`--check` / `--write`) - REPL:表达式回显、多行块、**↑/↓ 跨会话历史**、**Tab 补全** - `jishi 调试` 调试器:断点 / 单步(进·过·出)/ 看变量 / 看调用栈 / 就地求值;出错时打「出错那一帧的变量 + 调用栈」现场。 **树遍历 / 字节码(`--执行器 vm`)/ C 虚拟机(`--执行器 cvm`)三个执行器 都能调,会话记录逐字相同**(C VM 的就地求值除外,会明确说明) - `jishi 医生` 环境自检、`jishi 新项目` 脚手架、`jishi 教程` 本地索引、 **`jishi 错误 <码>`** 查错误码(什么意思 / 常见成因 / 怎么改,M56)、 **`jishi 升级` / `jishi 卸载 --自身`**(语言本体的升级与卸载,M110) - **标准库(M2 + M10 + M14 + M41 + M50 + M51 + M52 + M53 + M54 + M55 + M106 + M107 + M108 + M109 + M112 + M113 + M114 + M115 + **M117** + **M118** + **M119** + **M120** + **M122** + **M123**,共 **30 个中文模块**、**307 个函数**;除 `时间.计时` 一处已知缺口外,五个引擎同宽)**: - 📌 **M121 起「报错会告诉你怎么改」**:`模块.名字` 找不到时 —— ① 这个名字如果其实是**某个类型的方法**(`文本.去空白` / `容器.追加`), 直接点出来:「`「去空白」是文本的方法,不是模块函数`」; ② 真没有,就把这个模块里**有的**列出来(而不是以前那句 「`打印(dir(模块名))` 在后续版本可用」—— `dir` 根本没实现,是空头承诺)。 同轮把**模块门面**收紧到 `__all__`:以前 `import` 进来的实现细节 (`文本.RunTypeError`、`json.annotations`…)**28 个模块全都能访问到**。 - 📌 **M120 起「零碎但天天用」**:`路径.分隔符()` · `系统.CPU核数()` · `日期.月天数(年, 月)` (闰年规则自动对,**1900 不是闰年、2000 是**)· `时间.时区偏移()`(给 `+08:00`, **不是时区名**——名字三家拿到的口径完全不同,永远对不齐)· `json.有效(文本)` (与 `json.解析` **同一个解析器**,所以 `NaN`/`Infinity` 一律不算)· `表格.转文本(t)`(**对齐表**,汉字算 2 列、数字列右对齐)与 `表格.转TSV(t)`。 - 📌 **M119 起「GBK 与中文网址」**:`编码.GBK文本(字节)` / `编码.文本GBK(文本)` —— 国内大量老的 CSV / TXT 是 GBK,读进来终于是对的字;解不出 / 编不了都**明确报错**。 `网络` 的网址参数**自动做百分号编码**(直接写中文即可):只转非 ASCII 字符与空格, 结构字符 `/ ? & = # %` 一律保留 —— 所以「已编码的网址」不会被二次编码。 ⇒ **绕道台账 1 → 0**(三个探针全部「已毕业」)。 - 📌 **M118 起「复制整棵树 / 只看箱子里的一件 / 往后接字节」**: `文件.复制目录(源, 目标)`(**目标已存在就报错**——不自动合并/覆盖,那太容易把东西搞乱)、 `文件.追加字节(路径, 字节)`(`写字节` 是整份覆盖,这个是往后接)、 `压缩.解压成员(包路径, 成员名)`(**只取一件**,不用把整棵树铺到磁盘上)。 ⇒ **绕道台账 3 → 1**(只剩 R101 网址中文,留 M119)。 - 📌 **M117 起「卡区间 / 建索引 / 深拷贝 / 随机口令」**:`数学.限制(值, 底, 顶)`(返回入参之一, **保类型**)与 `数学.符号`(永远给 -1/0/1);`容器.索引表`(值 → **首次**出现的下标, 把「查一次」从 O(n) 变 O(1))与 `容器.深拷贝`(列表/字典递归复制,**改副本不影响原件**); `随机.随机文本(长度, 字符集)`(字符集用中文短名:字母数字/字母/小写字母/大写字母/数字) 与 `随机.按权重(选项们, 权重们)`。 - 📌 **M106 起「一个汉字算 2 列」**:`文本.左对齐` / `右对齐` / `居中` / `填充` 按 **显示宽度**补空格(以前按字符数,中文表格必歪),并新增 `文本.显示宽度(值)`。 **ASCII 的输出一个字节没变**。同批补了 `迭代.归约` / `迭代.分区`、 `表格.分组汇总` / `表格.连接`。 - 📌 **M107 起「网络与结构化数据」**:`网络` 从 3 个函数补到 6 个 —— `获取`/`提交`/`获取JSON` 都**能带请求头**(真实接口几乎都要鉴权头), 新增 `提交JSON`(发 `application/json`)、`获取详情`(拿状态码/响应头/正文, 非 2xx 不抛)、`下载`(存文件给字节数),报错统一成 `HTTP {状态码}`; `表格.从记录`/`转记录`(JSON 记录 ↔ 表格,不再落临时 CSV);`html` 加了解析方向 `取文本`/`取链接`/`取表格`(网页采集不再正则硬挖)。 - 📌 **M112 起「数据持久化」**:新增 `数据库` 模块(**真 SQLite**,标准文件格式 —— 基石建的库,任何 SQLite 工具、Python 的 `sqlite3` 都能直接打开)。 建表 / 插入 / 批量插入(事务)/ 查询(等值、比大小、包含、非空)/ 条数 / **汇总**(与 `表格.分组汇总` 同形状)/ 修改 / 删除 / 建索引 / 关掉再开 + 逃生口 `执行` / `执行查询`(直接写 SQL)。**不用写 SQL 就能干完小工具的活**, 要写 SQL 也随时能写。⚠️ 两条如实说:Rust 侧为此引了**唯一一个第三方依赖** (`rusqlite` bundled,代价是**构建需要 C 编译器**);浏览器试玩页(wasm) 不链 sqlite,`导入 数据库` 会**明确报「本平台不可用」**。 - 📌 **漂移检测有四道**(M51 + M54 + M55 + M56):**标准库的模块与函数**、 **对象方法**、**内建函数**(`列表`/`字典`/`文本`/`集合`/`文件`/`小数`)—— 前三道由宿主自己 `--dump-stdlib` / `--dump-methods` / `--dump-builtins` **报家底**,测试拿 Python 侧的 `--lang-spec` 去比; **第四道是「内建体检」**(`tools/probe_builtins.py`):不只比名字,而是给 **每个内建**一条最小程序,在**五个引擎上真跑**(M56 一建起来就抓到 `超()` 在两个宿主上根本不能用)。缺口一律**显式列在测试里并带断言**, 不许静默跳过。 - 📌 **M52 起,纯逻辑模块改成「用基石写一遍、五个引擎共用」**:`统计` / `容器` / `迭代` / `参数` **四个模块**已经迁到 `jishi/stdlib-jishi/`(编译期展开, 宿主零改动)。宿主层那几份**留着** —— 它们是回落,也是「迁移没改变行为」的 对照。见 `docs/设计决策.md` D45。 - 随机:随机整数 / 随机小数 / 随机选择 / 洗牌 - 数学:开方 / 幂 / 四舍五入 / 最大公约数 / 最小公倍数 / 阶乘 / 圆周率 / 三角 / 对数 - 时间:现在 / 今天 / 此刻 / 时间戳 / 星期名 / 加天数 / 高精度计时 / 睡眠 / **计时** - 文件:写文本 / 读文本 / 追加 / 写行 / 按行读 / 目录操作 / 路径工具 / **原子写**(先写临时再改名,写一半崩了不毁原文件) - 表格:读表格 / 挑选 / 筛选 / 排序按 / 汇总 / 追加 / 分组汇总 / 连接 / **从记录 / 转记录** —— 数据分析入门钥匙 - 文本:拼接 / 对齐(**按显示宽度**,M106)/ **显示宽度** / 补零 / 判断 / 去前缀后缀 / 格式化 / 截断 / 填充 - json(M10):转文本 / 解析 / 读文件 / 写文件(中文不转义) - 日期(M10 + M109):今天 / 格式化 / 加减天数 / **加月 / 加年**(按日历月, 月末自动收口)/ **解析ISO**(只取字面日期,不做时区换算)/ 相差天数 / 早于 / 晚于 / 相等 / 星期名 - 正则(M10):匹配 / 搜索 / 查找全部 / 替换 / 拆分 / 分组 - 网络(M10 + M107):获取 / 提交 / 获取JSON(都能带请求头)+ 提交JSON / 获取详情 / 下载 (urllib 薄封装,零第三方依赖,默认 10s 超时) - **数据库(M112)**:打开 / 关闭 / 表们 / 有表 / 建表 / 建索引 / 插入 / **批量插入**(事务)/ **查询**(条件 + 排序 + 条数)/ 条数 / **汇总** / 修改 / 删除 / 执行 / 执行查询 —— **真 SQLite**(标准文件格式),种子句柄就是路径文本 - 路径(M14 + M108):存在 / 是文件 / 是目录 / 绝对路径 / 父目录 / 文件名 / 后缀 / 连接 / 创建目录 / 列出 / 大小(pathlib)+ **递归列出 / 按模式找**(`报告*.md` 这类 通配找文件)/ **递归删除** / **系统临时目录 / 临时目录 / 临时文件** - 加密(M14 + M109):摘要 / md5 / sha1 / sha256 / sha512 / 文件摘要 + **HMAC**(带密钥的签名)/ **口令摘要**(PBKDF2,默认 10 万次)/ **安全随机字节** (系统熵源)(hashlib / hmac / secrets) - 压缩(M14 + M109):打包 / 解压 / 列出内容(zip)+ **压缩文件 / 解压文件** (**单个文件**的 `.gz`)(zipfile / gzip) - 系统(M14 + M108):系统名 / 环境变量 / 执行 / 退出码 / 主机名 / **打开** (跨平台用默认程序打开文件或网址,返回真假)(os/subprocess) - 容器(M41):计数 / 最多 / 按值排序 / 分组 / 取前 / 取后 / 分块(Counter 式统计;模块名不叫「集合」——那是内建函数名) - 迭代(M41 + **M50**):分组 / 滑窗 / 去重 / 展开 / 取前 / 取后 / 求和 / 计数 / **累积 / 组合 / 排列 / 笛卡尔积** - 参数(M41):新建 / 选项 / 标志 / 用法 / 解析(命令行选项解析) - 日志(M41):级别们 / 设级别 / 取级别 / 设前缀 / 调试 / 信息 / 警告 / 错误 - 测试(M41):用例 / 相等 / 不等 / 为真 / 为假 / 近似 / 包含 / 抛出 / 统计 / 汇总 - **统计(M50)**:求和 / 平均 / 中位数 / 众数 / 方差 / 标准差 / 极差 / 分位数 / 去极值平均 / 加权平均 - **编码(M50)**:base64 编解码 / 十六进制编解码 / URL 编解码 / 文本↔字节列表 - **配置(M50)**:读/写 JSON / 读/写键值文本 / 点号路径取·设 / 深度合并 / 展开(**不含 TOML**,见下) - **html(M50 + M107)**:转义 / `原样`(标记已生成片段)/ 标签 / 空元素 / 链接 / 属性文本 / 有序无序列表;**解析方向**:取文本 / 取链接 / 取表格 - **对比(M50)**:行级 diff——统一格式 / 逐行结构 / 并排 / 相似度 / 最相似 - **标识(M50)**:唯一标识(36 位)/ 短标识(22 位,URL 安全)/ 字节列表 - **标准库的跨语言宿主(M31)**:**M2/M10/M14/M41 的 19 个模块**在 Node 与 Rust 宿主上都可用(压缩是手写 zip 容器、网络用子进程同步封装,都与 Python 侧逐字节对拍); 文件读写**换行保真**(写 `\n` 就是 `\n`,同一份程序在两个平台产出相同字节)。 ✅ **M50 新增的 6 个模块(统计/编码/配置/html/对比/标识)也已同步到两个宿主** (M50 第二批):Node 与 Rust 侧都实现好了,**五引擎逐字节对拍** (`tests/test_m50_hosts.py`,39 项)。Rust 侧的 base64 / 行级 diff / UUID 都是自写的(它零第三方依赖)。 ⚠️ **`配置` 不含 TOML**:基石当前没有 toml 解析器(Python 的 `tomllib` 要 3.11+), 为不引入版本依赖只做了 JSON 与键值文本;要 TOML 得单独立项。 ✅ **M51 把两宿主的账对平了**:新增 `--dump-stdlib`(宿主自报家底)+ `tests/test_m51_consistency.py` 漂移检测(Python 侧有、宿主没有就报红), 并补齐 **13 个此前静默缺失的函数**(Node 12 / Rust 6:`数学` 三角函数与对数、 `文本.填充/截断`、`迭代.累积/组合/排列/笛卡尔积`)。宿主**命名参数**也不再被 静默丢掉 —— `加密.摘要("abc", 算法="md5")` 五个引擎给同一结果。 ⚠️ 唯一剩下的缺口是 `时间.计时`(见上)。 - **语法补充(M2)**:尾随逗号(`[1, 2, 3,]`)、括号内跨行书写列表/字典/参数 - **Python 生态桥接(M3)**: - `导入 math 从 python`、`导入 pandas 从 python 为 数据框`——直接用整个 Python 生态 - Python 对象属性/方法直接访问:`datetime.datetime.now().year` - 基石函数可直接传给 Python 高阶函数(map/filter/sorted 回调) - Python 异常自动翻译成中文(文件找不到、权限不足、递归过深…) - **关键字参数**:`json.dumps(x, ensure_ascii=假)` —— 中文不转义的关键 ```python 导入 json 从 python 打印(json.dumps({"姓名": "小明"}, ensure_ascii=假)) # {"姓名": "小明"} ``` 基石函数同样支持:`介绍(姓名 = "小红", 年龄 = 8)` - **教程**:`docs/tutorial/` **全 10 章**已完成(从你好世界到记账程序综合实战, 再到语法糖/沙箱 MCP/包管理),配套示例在 `examples/tutorial/`,示例全可运行 ## 教程目录 | 章节 | 内容 | |------|------| | [01 你好基石](docs/tutorial/01_你好基石.md) | 运行基石、打印、变量、注释 | | [02 数与文本](docs/tutorial/02_数与文本.md) | 运算、字符串方法、输入、列表 | | [03 判断与循环](docs/tutorial/03_判断与循环.md) | 如果/否则、遍历/循环/当、链式比较 | | [04 函数](docs/tutorial/04_函数.md) | 定义函数、作用域、递归 | | [05 字典与结构化数据](docs/tutorial/05_字典与结构化数据.md) | 键值对、嵌套、计数器 | | [06 文件与标准库](docs/tutorial/06_文件与标准库.md) | 文件读写、数学/时间/表格模块 | | [07 综合实战](docs/tutorial/07_综合实战.md) | 记账程序:需求→设计→实现 | | [08 语法糖](docs/tutorial/08_语法糖.md) | 多赋值解包/默认参数/推导式/文本插值 | | [09 沙箱与 MCP](docs/tutorial/09_沙箱与MCP.md) | 沙箱三道保险/统一协议/MCP Server | | [10 包管理](docs/tutorial/10_包管理.md) | 安装/卸载/列表/依赖解析 | ## 项目结构 ``` oracle/jishi/ 【判据基准】Python 实现:词法/语法/AST/语义/报错/执行内核/标准库 (已退役,不分发、不给安装入口;`python -m oracle.jishi.cli`) tokenizer.py 词法分析(缩进栈、全角归一化、中文分词消歧、中文引号) ⚠️ `JISHI_FRONTEND=rust` 时 `tokenize()` 转发给 `core/`(R2) _core.pyd Rust 前端的扩展模块(**本机现编、不进仓库**,见 core/build.py) parser.py 语法分析(递归下降+优先级爬升,链式比较、尾随逗号、容错解析) ⚠️ `JISHI_FRONTEND=rust` 时 `parse_source()` 转发给 `core/`(R3); 生产入口是 `parse_source(源码)`,`parse(tokens, lines, f)` 留给 LSP 增量分词(按行复用前缀,见「R 线」的前端契约) ast_nodes.py AST 节点(dataclass, kw_only=True) errors.py 中文错误体系(E01xx词法/E02xx语法/E03xx语义/E2xxx运行) interpreter.py 树遍历解释器(作用域链/闭包/对象方法分派/内建函数,默认执行器) runtime.py 共享运行时语义(方法表/内建/属性/调用/导入,三执行器共用) opcodes.py 指令集(唯一事实来源,C 头文件由此生成) compiler.py 字节码编译器(作用域分析/闭包单元/指令带行列) vm.py Python 参考字节码虚拟机(M4a) cvm_bind.py C VM 的 ctypes 绑定 + 宿主回调实现(M4b) ai.py AI 元数据统一数据源:语言卡 / 语言规格 / 错误序列化(M8) protocol.py 统一执行结果协议(M9.2) sandbox.py 沙箱运行器(超时/stdout 上限/模块白名单,M9.1) mcp_server.py MCP Server(stdio 传输,run_script/eval_expr,M9.3) serialize.py 跨语言字节码序列化(M13.1,JSON 格式 + 版本 + 校验和) packages.py 包管理:远端索引格式 + 版本约束 + 安装/卸载(M10.2/M14) debugger.py 调试器(M37 树遍历 / M39 字节码 / M40 C VM;一套会话 + 三个执行器适配) incremental.py 增量分词(M38 B2:按行复用前缀的 token 与词法状态) lineedit.py REPL 行编辑(M38 B3:历史 / Tab 补全 / 光标编辑,按键可注入) langdata.py 语言元数据提炼层(LSP 与 REPL 共用,来自 ai.build_lang_spec) cli.py CLI 入口(run/--ast/-i/--ai-card/--lang-spec/--sandbox/调试/安装/卸载/列表…) repl.py 交互式 REPL(回显/多行块/帮助/清空) jishilib.py 基石库层(M52):**用基石写的标准库**的发现 / 包装 / 展开 (设计见 docs/设计决策.md D45) stdlib/ 标准库 30 模块(基础 19 个 + M41 容器/迭代/参数/日志/测试 + M50 统计/编码/配置/html/对比/标识 + M112 数据库 + M114 并发 + M115 HTTP服务端; 清单见上「已经能做什么」) stdlib-jishi/ **用基石自己写的**标准库(M52):纯逻辑模块只写一份,编译期 展开进主程序,五个引擎共用同一份字节码;目前有 统计.jsh cvm/ C 执行内核(M4b) bytecode.md 字节码设计文档(指令集/值表示/宿主协议/重入/异常协议) build.py 一键构建(生成 opcodes.h + gcc 出 DLL/SO,支持 --out) include/jsvm.h 公开 C ABI 头文件(M9.4,JSVM_ABI_VERSION=1) include/opcodes.h 指令码头文件(由 opcodes.py 生成,两侧同步) src/jsvm.c C 虚拟机主循环 oracle/node/ 【判据基准】Node.js 纯 JS 解释器(零依赖,消费 JSON 字节码;标准库全同步, M51 起有 `--dump-stdlib` 自报家底供一致性检测) rust/ **正式实现**:jishi-ffi crate(自研零依赖 JSON 解析器 + 零依赖标准库, M51 起有 `--dump-stdlib`;`jishi-rs` 是完整宿主,跑源码走 前端 → 字节码 → Rust VM);`selfupdate.rs` 管语言本体的升级 / 卸载(M110) frontend/ **R7.1** 前端核心抽出的独立 crate `jishi-frontend`(纯 Rust、零依赖; core/ 只剩 pyo3 搬运壳,wasm 也复用它) wasm/ **R8.1/R8.2** 浏览器入口 crate `jishi-wasm`:把整条链编到 `wasm32-unknown-unknown`(**裸 C ABI,不上 wasm-bindgen**); jishi-wasm.js 是手写胶水(源码唯一一份), 构建走 tools/build_wasm.py(产物 site/jishi_wasm.wasm,1.56 MB) core/ **R 线(R2 起)**:前端核心的 Rust 落地(pyo3 编成 Python 扩展) build.py 一键构建(生成 pyo3 配置 + cargo build + 复制成 jishi/_core.pyd); ⚠️ 两个环境坑写在它的 docstring 里,**别手敲 cargo** src/tokenizer.rs 词法分析器(`jishi/tokenizer.py` 的逐行为移植,目标「逐 token 一致」) src/parser.rs 语法分析器(`jishi/parser.py` 的逐行移植,含全部解析期脱糖) src/compiler.rs 编译器(`jishi/compiler.py` 的逐行移植 → 字节码) src/jishilib.rs 基石库层展开(`导入 统计` → 一次函数调用) src/serialize.rs 字节码 JSON + `repr(float)` 复刻 src/opcodes.rs 50 条指令(这份编号的第三份拷贝,靠 `opcode_table()` 对拍防漂) src/sha256.rs 字节码 checksum(零依赖) src/lib.rs Python 扩展入口(只做搬运:Rust 结果 → Python 对象 / 错误) tests/ 测试(含三执行器对拍 + 跨宿主对拍 + M51/M54/M55 漂移检测 + R2/R3/R4 的 Rust 前端守门测试 `test_m59_tokenizer_rust.py` / `test_m60_parser_rust.py` / `test_m61_frontend_errors.py`) examples/ 示例与真实程序:tutorial/(10 课配套示例)、projects/(6 个真实项目, 参与行数比)、绕道探针/(撞标准库缺口的「量尺」,**不**参与行数比)、 ai/(few-shot 库)、embed/(C 嵌入示例)、packages/(包管理示例) docs/ 语言规格.md(语法/语义/标准库 API)、设计决策.md(D1 起的取舍记录)、 调试器.md、工具链.md(LSP/REPL/格式化)、真实项目.md、embed.md(嵌入其它宿主)、 ai/(系统提示词 / 提示词指南)、tutorial/(教程 10 章)、 版本历史/(**归档区:只作历史,不是设计参考**) assets/ 品牌资产(基石_logo.png,源图 基石_logo.jpeg) tools/ run_tests.py 测试 / benchmark.py 基准 / build_site.py 文档站 / build_home.py 官网六页(数字从 --lang-spec 读、示例真跑自检)/ build_index_mirror.py 索引改写(自建源那份的下载地址)/ fetch_release_mirror.py 发行包镜像(从 GitHub Releases 取,校验和核对)/ conformance.py 一致性夹具(前端四阶段 vs 冻结基线,架构迁移的验收闸门; `emit --frontend rust` 让 Rust 前端自己交产物)/ bench_frontend.py 分词+语法吞吐(Python vs Rust 交错 A/B,算出**端到端天花板**)/ probe_errcodes.py 错误码体检(R4:「表里有」≠「会出现」)/ check_engines.py 三执行器体检(R5.1:全语料 + 报错文本,逐字节比)/ bench_frontend.py 分词+语法+编译三段吞吐/ site_sync.sh 服务器侧部署(web 根 + Nginx + 隐私终检)/ deploy_push.sh 本地构建 + 推送(密钥/地址只从环境变量读)/ nginx-jishi.conf / -tls.conf / -locations.conf 站点配置(80/443/共用)/ loc_ratio.py 行数比统计(基石 vs Python 参考实现) / gen_stdlib_sigs.py 标准库签名表生成(两宿主的命名参数靠它,M51) / probe_builtins.py 内建体检(每个内建 × 五引擎真跑,M56) / bench_jishilib.py 基石库层 vs 宿主层的倍数(M52) / build_playground.py 浏览器试玩(R8.2 起跑 wasm 引擎)/ build_wasm.py wasm 引擎构建(cargo → site/jishi_wasm.wasm + 胶水)/ build_wheel.py wheel 打包 / ci.py 一键全检 / publish_github.py 公开仓库同步(唯一发布通道) ``` ## 架构与数据流 ``` 源码 ──→ tokenizer ──→ parser ──→ AST ──┬─→ 树遍历解释器(walk,参考执行器) (Rust 前端,同一份代码 └─→ 编译器 → 字节码 ──┬─→ Rust VM(默认,进程内) 还编到 wasm) └─→ C VM(jsvm,独立二进制) ``` - **正式实现只有两套**:**Rust**(前端 + 字节码 VM + 完整宿主 `jishi-rs`,`rust/` + `frontend/`)与 **C 虚拟机**(`cvm/`)。**Python / Node 已退役**到 `oracle/`, 只作**判据基准**(不分发、无安装入口)。多个执行器**逐字节对拍**, `tests/test_cvm.py` 护航「换执行器不改变任何可观察行为」(stdout 与报错一致)。 - **前端四阶段(源码 → 词法 → 语法 → 字节码)在 Rust 原生跑**:`frontend/` 是纯 Rust 零依赖 crate,`core/` 只剩 pyo3 搬运壳(`JISHI_FRONTEND=rust` 时给 Python 前端用), `wasm/` 也复用它。对 **103 语料 × 四个阶段逐字节一致**(`tools/conformance.py`); 「源码 → 字节码 JSON」这条路上**端到端 5.37x**(`tools/bench_frontend.py` 每轮重算并**把推导印出来**)。 - **两条执行路径的性能边界**(`tools/benchmark.py` 为准):C VM **纯算术 11–48x**、**列表构建与遍历 14x 上下**、**字典写入 6x 上下**、 **文本拼接约 3x、文本比较约 12x**(M47:文本改成 **C 侧原生字符串**, 拼接与比较不再回调宿主)、**浮点 / 布尔遍历 6x 上下**。 ⚠️ **宿主回调是 C VM 的已知瓶颈**:每次内建 / 方法 / 标准库调用固定约 **2.4µs** (C↔宿主 FFI 往返,**与被调函数做什么无关**),所以「内建调用密集」只有 0.91x。 **要提速就得减少回调次数**,而不是把回调内部写得更快。**文本下标 / 切片 / 遍历**、 **字典查找(读没法合并)** 都受这条制约 —— 这些边界都逐字记录在 `tools/benchmark.py`,是**已知边界、不是待修缺陷**。 - **在线试玩跑的就是这套引擎**(R8.1/R8.2):Rust 前端 + 字节码 VM + 原生标准库编到 `wasm32-unknown-unknown`(`wasm/` crate,**裸 C ABI**、不上 wasm-bindgen, 模块 1.56 MB);浏览器里**不再另跑一份 Python 实现**。 - **AI 原生能力**(M8/M9/M116)架在 AST 与报错之上:语言卡(`--ai-card`,**带完整签名、可单模块/按任务分片**)与语言规格 (`--lang-spec`)从**同一份**语言事实产出,结构化报错带错误码与「你是不是想写…」 建议;`jishi mcp` 把执行能力暴露给任意 MCP 宿主。 ## 环境要求 - **使用**:从 下载对应平台的发行包(Windows 安装程序 / Linux / macOS 压缩包)—— 发行版是 **cargo 单二进制**,**不用先装 Python**, 也**没有 `pip install` 这条路**(见上「安装」一节)。 - **从源码开发**:需要 **Rust 工具链**(构建前端 + 宿主 + C VM 的宿主侧), 以及 **C 编译器**(`python cvm/build.py` 构建 C 虚拟机:MinGW-w64 / gcc / clang 均可; 没有也能跑,C VM 自动降级)。 - **Python ≥3.13**:**只用于构建脚本与测试套件**(生成语言卡、构建站点、 跑判据对拍),**不是运行时依赖**。运行时零第三方依赖;测试用 pytest, `tools/make_logo.py` 图像处理用 pillow —— 均为开发期工具。 (2026-10-10 起 CI 只测这一个版本:原先的 3.10 + 3.13 两档是照作者本机设的, 对这个语言项目并非真需求;跨版本语法陷阱另由 `test_m57_conformance.py` 的 AST 扫描兜底。) - Windows 注意:venv 可执行文件在 `Scripts/` 而非 `bin/`。 ## 开发:运行与测试 ```bash # 运行脚本 / 交互式 REPL / 查看 AST python -m oracle.jishi.cli examples/01_猜数字.jsh python -m oracle.jishi.cli -i python -m oracle.jishi.cli examples/01_猜数字.jsh --ast # 全部测试 python -m pytest tests/ # 一键构建 C 虚拟机 DLL python cvm/build.py # 性能基准(树遍历 vs C VM) python tools/benchmark.py ``` ## 关键技术决策(详见 docs/设计决策.md) - **D1 技术栈透明**:Python 前端 + C 内核 + Python 生态桥接,不 fork/patch CPython - **D2 分词消歧**:关键字粘连检查只针对**多字关键字**(如果/循环/导入…), 单字关键字(类/当/真/空/非/令)不做前缀检查,否则 `类型`/`当时`/`空间` 等日常词全被误伤。 - **D3 全角标点**:字符串与注释外做一对一归一化(`=`→`=` 等);全角空格 U+3000 在缩进中报错。 - **D4 执行模型**:树遍历 → 字节码 + C VM(M4),语法不变,对拍测试保证一致。 - **D5 标准库**:中文 API 是薄壳,绝不重造轮子,真实价值来自 Python 生态。 - **D7 对象方法分派**:方法表按类型分派返回闭包,列表方法原地修改、文本方法返回新值。 - **D8 REPL**:顶层表达式非空回显(真/假/空中文化);空行强制结束多行块。 - **D11 异常对象模型(M5a)**:异常即 `JishiError` 实例,`e.消息`/`e.类型` 可读; 捕获条件按类型名匹配,用 isinstance 判断(基类抓子类)。 - **D12 语法用中文助词(M5a)**:`捕获 值错误 为 e:`、`继承 基类:` 用「为/继承」 等助词连接,不用冒号嵌套的类 Python 写法,读起来更像自然语言。 ## 已踩过的坑(避免重踩) 1. `re.fullmatch` 对 `[...]` 单字符类多字符永远 False,要用 `[...]+` 运行正则。 2. dataclass 继承字段顺序 → 全部 `@dataclass(kw_only=True)`。 3. 全角引号需配对表(`“` 配 `”`),不是同字符闭合。 4. 块语句以 DEDENT 结束,parser 主循环不能要求 NEWLINE。 5. `与/或` 右操作数要用 `parse_expr(prec+1)` 而非 `parse_unary()`,否则比较运算符逃逸。 6. `dump_ast` 用 `vars()` 前先判类型(tuple/list 无 `__dict__`)。 7. Windows venv 路径 `Scripts/` 不是 `bin/`。 8. 尾随逗号:列表/字典/调用参数/函数参数四处循环都要支持(M2 已修)。 9. `数学.幂` 用 `math.pow` 返回 float,整数期望 int → 用 `**` 运算符。 10. `导入 文本` 会遮蔽内建 `文本()` 转换函数(与 Python 导入遮蔽一致,文档已注明)。 11. 调用括号内的 `名字 = 值` 一律按关键字参数处理(parser 调用上下文无赋值语义)。 12. `_lookup` 查英文 True/False/None 的提示要在"你是不是想写"建议**之前**抛出, 否则编辑距离建议会给出误导性结果。 13. 三执行器共享 runtime 语义,但异常穿透调用栈的「重入边界」必须一致 (vm.py 的 stop_at / C VM 的 stop_depth),否则类方法里 `抛出` 会被错误接住。 14. `非` 的优先级必须**低于比较运算**(M23 修正)。写成一元(最紧)会让 `非 年龄 >= 18` 变成 `(非 年龄) >= 18` 恒为假——**静默给错答案**, 项目教程自己就踩过。现按 Python `not` 语义:`非` 吃掉右边的比较表达式, 吃不掉 `与/或`。 15. 新增比较运算码(`在`/`不在`/`是`/`不是`)要放在 **6–9**,不能占用 0–5: 0–5 是 C VM 的 `compare_fast` 快路径,6 以上自动回落宿主回调 `host->compare`——这是「加语义比较运算符零 C 改动」的前提(见 opcodes.CmpOp)。 16. C VM 里同一个函数每次跨边界都会新建 `CvmFunction` 包装,直接按 `id()` 判断同一性会与另两个执行器结果相反(`f 是 g`)。修法是按 `JVal.v.u` (底层 `JsFunc*` 指针)缓存包装(见 `cvm_bind.CvmHost._func_cache`)。 17. 加比较类关键字(`不在`/`不是`)必须同时加进 tokenizer 的 `_GLUE_CHECK_SKIP`:它们本身是常用词前缀,否则 `不在列表`、`不是我` 这类正常变量名会被「关键字粘连」检查误报。 ## 往哪走 **定位(2026-09 调整)**:北极星从「最容易被大模型正确生成」务实调整为 **「健全语言自身能力,让编程者方便实现意图,出问题能快速定位」**; 「AI 友好」降为辅助线带着走。 **0.2.x 沿两个方向继续**(见上「当前进度」):**v0.2.2 已发布**(架构变革收官), **v0.2.3 把标准库补厚 + 补上语言本体的升级 / 卸载**(M105–M111)。分两段走: | 段 | 做什么 | 状态 | |---|---|---| | **① 先把标准库补充完整** | 按**真实项目驱动**定范围:拿真实小程序去跑,看它们缺什么,**按实际缺口补**(不是照别的语言抄清单);补一处就补一条判据(五个引擎同宽) | ✅ **M105–M109 已交付**(0.2.3) | | **② 再往「契合 AI」深入** | 语言事实已机器可读(语言卡 / 结构化报错 / 错误码 / few-shot)。下一步让大模型**更容易一次写对**:语言卡**带签名 + 分片**、常见任务的惯用写法、更可操作的报错、能真跑通的示例 | 🚧 0.2.5 | > **0.2.4 起**:按真实场景补**新增大类**(数据持久化 SQLite / 并发 / HTTP 服务端)—— > 一律过**准入三关**、由真实项目撞出来才算数,量不出收益就如实写「不做」。 > **0.3.x 暂缓**:原定义(「架构变革完成之后」)跨度太大,已作废 —— 等 0.2.x 走完再重新定义。 > 版本号沿 **0.2.3 / 0.2.4 / 0.2.5…** 连续推进,不跳号。 R 线各步的交付明细见 `docs/版本历史/`(归档区)。更远的规划 (准入标准 / 不做清单 / 度量体系 / 遗留项逐条结论)在内部路线图(不公开)。 每个阶段维持既有纪律:**可演示成果 + 测试护航 + git 提交**; 新特性准入三关:**真实需求驱动 / 可度量验收 / 投入产出比**, 外加「关 0」:能用内建/标准库实现的,不碰语法。 ## 设计原则 1. **像 Python 一样简洁**:缩进划分代码块,语法零冗余。 2. **中文是母语**:报错信息全中文,精确到行列,附"你是不是想写…"修正建议。 3. **生态即生命**:绝不重造标准库,薄封装 Python 生态。 4. **透明不吹牛**:技术栈如实标注,走长期演进路线。 ## 声明 本项目以 **MIT-0**(MIT No Attribution)许可证发布,全文见 [`LICENSE`](LICENSE)—— 可自由使用、修改、分发、商用,**无需署名**。只期望这个语言(或者说这个工具)能有所用途, 毕竟做个中文的编程语言,是我一直以来的夙愿,但是一直受限于没有相关的技术能力,所以迟迟没有动手。也有幸在这个时代可以使用大模型来帮助自己塑造自己期望的软件产品,所以我就试着去实现自己的想法了,大家如果有什么建议也可以和我说,我的邮箱是benxiaoniao@outlook.com 可用 / 50 项
里程碑
36 个已完成
模块规模
22158 行 Python
示例程序
32 个 .jsh

这个页面是谁生成的

整套页面由 examples/projects/基石自述站/生成.jsh 生成——它本身就是一个用基石写的程序,读的是仓库里的真数据(版本号来自 pyproject.toml,测试数与探针来自 README.md,里程碑来自 PROGRESS.md,模块规模与示例数是当场统计的)。所以这页上的数字不会过期,重新跑一次就刷新了。

最近的里程碑

里程碑内容完成
**M17**排错体验补全(递归翻译 bug + 调用栈 + 协议补全 + REPL 源码行)✅ 2026-09-06
**M18**表达便利(切片 / argv / 最小二参 / 遮蔽治理)✅ 2026-09-06
**M19**发行改进(Windows 安装程序 + 三平台自动构建)✅ 2026-09-12