From 2d23dfec3e99a0ca752be3a593f8a48b971a18c4 Mon Sep 17 00:00:00 2001 From: "peng.li24" <734991033@qq.com> Date: Fri, 11 Sep 2026 17:24:47 +0800 Subject: [PATCH] =?UTF-8?q?spec:=20=E6=95=B4=E5=90=88=E8=87=AA=E6=B4=BD?= =?UTF-8?q?=E5=8C=96=20spec=20=E6=A0=91=EF=BC=8884=20=E7=AB=A0=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 按裁决全量改写 stdlib/kvlang/spec/ 下 54 章,收敛类型系统/kvspace 模型/ layout/runtime/编译器语义表述,spec 为准。净 -134 行。 Co-Authored-By: Claude Opus 4.8 --- ...05\350\257\273\347\272\246\345\256\232.kv" | 2 +- ...16\344\274\230\345\205\210\347\272\247.kv" | 2 +- ...60\345\235\200\347\251\272\351\227\264.kv" | 5 +- ...00\344\270\216\345\221\275\345\220\215.kv" | 7 +- .../04-CABI.kv" | 6 +- ...60\347\273\204\350\256\277\351\227\256.kv" | 20 +- ...ad\347\272\277\346\240\274\345\274\217.kv" | 6 +- ...51\347\220\206\345\275\242\346\200\201.kv" | 11 +- ...03\345\261\200\346\240\274\345\274\217.kv" | 39 ++- .../09-\350\260\203\347\224\250extindex.kv" | 27 +- ...73\347\273\237\345\217\230\351\207\217.kv" | 13 +- ...32\345\256\275\347\261\273\345\236\213.kv" | 2 +- ...66\351\227\264\345\256\271\345\231\250.kv" | 16 +- ...16\347\211\271\346\256\212\345\200\274.kv" | 4 +- ...13\350\241\250\350\276\276\345\274\217.kv" | 47 +-- ...36\344\270\216\345\255\230\345\202\250.kv" | 27 +- ...16\345\220\210\346\263\225\346\200\247.kv" | 6 +- ...11\344\270\216\345\217\230\345\217\202.kv" | 15 +- ...60\347\273\204\345\275\242\346\200\201.kv" | 4 +- ...1-stringkeymap\345\275\242\346\200\201.kv" | 2 +- .../16-ptr.kv" | 3 +- .../17-struct.kv" | 3 + ...73\344\275\223\346\226\271\346\241\210.kv" | 4 +- ...30\345\202\250\344\275\215\347\275\256.kv" | 7 +- ...51\347\220\206\345\270\203\345\261\200.kv" | 10 +- ...16\347\255\276\345\220\215\350\241\214.kv" | 28 +- ...55\344\271\211\347\261\273\345\236\213.kv" | 12 +- ...03\345\261\200\347\244\272\344\276\213.kv" | 3 +- ...5-\345\267\262\346\225\262\345\256\232.kv" | 28 +- ...44\346\247\275\347\274\226\347\240\201.kv" | 6 +- .../03-\345\207\275\346\225\260.kv" | 101 +++--- ...75\344\270\216\345\270\203\345\261\200.kv" | 8 +- ...ut\346\265\201\346\260\264\347\272\277.kv" | 5 +- .../08-layout-abi.kv" | 15 +- ...70\350\247\201\350\257\212\346\226\255.kv" | 2 + ...44\270\216rwir\346\225\260\346\215\256.kv" | 15 +- ...70\203\345\261\200\344\270\216def-rwir.kv" | 4 +- ...47\350\241\214\346\250\241\345\236\213.kv" | 7 +- ...4\346\250\241\345\236\213-\347\273\255.kv" | 6 +- ...20\345\221\230\350\256\277\351\227\256.kv" | 9 +- ...75\346\225\260\350\260\203\347\224\250.kv" | 68 ++-- .../05-runtimec\345\206\205\345\273\272.kv" | 7 +- ...00\345\217\221\350\247\204\350\214\203.kv" | 2 +- .../07-notinmyrwircaps.kv" | 4 +- .../08-myrwir\346\211\251\345\261\225-c.kv" | 2 +- ...344\270\216\345\220\216\347\253\257abi.kv" | 292 ++---------------- ...45\220\216\347\253\257abi-\347\273\255.kv" | 4 +- ...21\345\231\250\345\256\232\344\275\215.kv" | 4 + ...16\347\253\257\347\256\227\345\255\220.kv" | 6 +- ...10\346\234\254\344\274\230\345\205\210.kv" | 6 +- ...07\347\232\206\346\230\216\346\226\207.kv" | 7 +- ...60\346\215\256\347\273\223\346\236\204.kv" | 31 +- ...76\345\274\217\346\226\207\346\263\225.kv" | 10 +- .../04-\346\214\207\344\273\244.kv" | 2 +- 54 files changed, 424 insertions(+), 558 deletions(-) diff --git "a/stdlib/kvlang/spec/00-\345\257\274\350\250\200/02-\350\247\204\350\214\203\347\224\250\350\257\255\344\270\216\351\230\205\350\257\273\347\272\246\345\256\232.kv" "b/stdlib/kvlang/spec/00-\345\257\274\350\250\200/02-\350\247\204\350\214\203\347\224\250\350\257\255\344\270\216\351\230\205\350\257\273\347\272\246\345\256\232.kv" index 1959a901..344bb118 100644 --- "a/stdlib/kvlang/spec/00-\345\257\274\350\250\200/02-\350\247\204\350\214\203\347\224\250\350\257\255\344\270\216\351\230\205\350\257\273\347\272\246\345\256\232.kv" +++ "b/stdlib/kvlang/spec/00-\345\257\274\350\250\200/02-\350\247\204\350\214\203\347\224\250\350\257\255\344\270\216\351\230\205\350\257\273\347\272\246\345\256\232.kv" @@ -17,6 +17,6 @@ lib kvlang/spec/导言/规范用语与阅读约定 { - 文法元记法与本规范其余用语约定见 [[文法]]。 - 完整权威文法汇总于 [[文法]](附录);正文各章只引用其片段,不各自另立文法。 -- 章节间引用以 `[[章节名]]` 链接。 +- 章节间引用用双方括号括住章节名(如 `[[文法]]`)。 "#### -> /lib/kvlang/spec/导言/规范用语与阅读约定 } diff --git "a/stdlib/kvlang/spec/01-\350\257\215\346\263\225/09-\351\200\273\350\276\221\344\275\215\350\277\220\347\256\227\344\270\216\344\274\230\345\205\210\347\272\247.kv" "b/stdlib/kvlang/spec/01-\350\257\215\346\263\225/09-\351\200\273\350\276\221\344\275\215\350\277\220\347\256\227\344\270\216\344\274\230\345\205\210\347\272\247.kv" index 83786a31..9856219d 100644 --- "a/stdlib/kvlang/spec/01-\350\257\215\346\263\225/09-\351\200\273\350\276\221\344\275\215\350\277\220\347\256\227\344\270\216\344\274\230\345\205\210\347\272\247.kv" +++ "b/stdlib/kvlang/spec/01-\350\257\215\346\263\225/09-\351\200\273\350\276\221\344\275\215\350\277\220\347\256\227\344\270\216\344\274\230\345\205\210\347\272\247.kv" @@ -19,7 +19,7 @@ lib kvlang/spec/词法/逻辑位运算与优先级 { 分别为按位与、按位或、按位异或、左移、右移。 `&` 一符二用,靠位置区分(同 C):操作数之后为中缀**按位与**;表达式起始或运算符之后为一元前缀 -**取址**(见下 [[取址运算符 `&`]])。 +**取址**(见下「取址运算符 `&`」)。 ## 取址运算符 `&` diff --git "a/stdlib/kvlang/spec/02-kvspace\346\250\241\345\236\213/01-\345\234\260\345\235\200\347\251\272\351\227\264.kv" "b/stdlib/kvlang/spec/02-kvspace\346\250\241\345\236\213/01-\345\234\260\345\235\200\347\251\272\351\227\264.kv" index a2ea62a2..18b1d338 100644 --- "a/stdlib/kvlang/spec/02-kvspace\346\250\241\345\236\213/01-\345\234\260\345\235\200\347\251\272\351\227\264.kv" +++ "b/stdlib/kvlang/spec/02-kvspace\346\250\241\345\236\213/01-\345\234\260\345\235\200\347\251\272\351\227\264.kv" @@ -29,8 +29,9 @@ ref=2(@ext,见 [[键系统与数组访问]]),其 body 只记录目标位 | GPU 显存 | 计算张量 | | 文件系统 / 对象存储 | 模型权重、检查点、数据集、外部进程输出 | -读取一个 ref=2 扩展句柄 value 时,运行时按 body 定位符前缀路由到对应兑现器还原真实字节 -(`runtime-rs/src/engine.rs`)。 +读取一个 ref=2 扩展句柄 value 时,由**支持 `@` 的 rwir** 按定位串还原真实字节——例如 runtime-rs 的 +networld/fs 一族 rwir 直接以 `@` 开头的扩展 key 为输入(`runtime-rs/src/engine.rs` 的 `read_at` / +`resolve_ext`)。核心 runtime-c 不解引用 `@`。 ## 后端与前端 diff --git "a/stdlib/kvlang/spec/02-kvspace\346\250\241\345\236\213/03-\345\257\273\345\235\200\344\270\216\345\221\275\345\220\215.kv" "b/stdlib/kvlang/spec/02-kvspace\346\250\241\345\236\213/03-\345\257\273\345\235\200\344\270\216\345\221\275\345\220\215.kv" index 88cc0656..30647a1a 100644 --- "a/stdlib/kvlang/spec/02-kvspace\346\250\241\345\236\213/03-\345\257\273\345\235\200\344\270\216\345\221\275\345\220\215.kv" +++ "b/stdlib/kvlang/spec/02-kvspace\346\250\241\345\236\213/03-\345\257\273\345\235\200\344\270\216\345\221\275\345\220\215.kv" @@ -23,8 +23,9 @@ PC 落在 kvspace、帧根落在 kvspace,故执行现场可观测、可崩溃 ## 变量名即指针 -kvlang 没有取址运算符——**代码中变量的名字,本身就是该变量的指针**(一条 kvspace 路径)。指令槽里存的 -从来不是值,而是指针文本;求值恒经一次指针间接。指针有两种形态: +**代码中变量的名字,本身就是该变量的指针**(一条 kvspace 路径)kvspace/kvlang是路径寻址,而不是64位寻址。指令槽里存的从来不是值,而是指针文 +本;求值恒经一次指针间接。`&x`(`≡ kv·abs(x)`)是取址语法糖,取到的是 kvspace 路径串,**不是**私有内 +存地址(见 [[运算符基础]])。指针有两种形态: | 形态 | 写法 | 语义 | 解析 | |------|------|------|------| @@ -55,7 +56,7 @@ kvspace 路径与 XValue 的 langtype 共用一套分隔符语义,每个分隔 | 分隔符 | 码位 | 语义 | |--------|------|------| | `/` | U+002F | 层级;目录以尾随 `/` 标记 | -| `·` | U+00B7 | **两种独立含义,正交**(见 [[总体方案]]):①**memindex 标记**——值容器成员索引 `{key}·`(仅 stringkeymap/struct 用),以及成员访问 `obj·field`、`m·[i]`;②**包·函数命名分隔符**——`/lib/{pkg}·{func}` 中路径段名字的一部分,rwfunc 目录成员仍走 `/` 子路径,与 memindex 无关 | +| `·` | U+00B7 | **两种独立含义,正交**(见 [[总体方案]]):①**memindex 标记**——值容器成员索引 `{key}·`(仅 stringkeymap/struct 用),以及成员访问 `base·field`、`m·[i]`;②**包·函数命名分隔符**——`/lib/{pkg}·{func}` 中路径段名字的一部分,rwfunc 目录成员仍走 `/` 子路径,与 memindex 无关 | | `‥` | U+2025 | 运行时系统变量前缀(`X/‥pc`,见 [[系统变量]]) | | `…` | U+2026 | extindex 句柄 body 的首元素前缀 | diff --git "a/stdlib/kvlang/spec/02-kvspace\346\250\241\345\236\213/04-CABI.kv" "b/stdlib/kvlang/spec/02-kvspace\346\250\241\345\236\213/04-CABI.kv" index b63129a4..f418102a 100644 --- "a/stdlib/kvlang/spec/02-kvspace\346\250\241\345\236\213/04-CABI.kv" +++ "b/stdlib/kvlang/spec/02-kvspace\346\250\241\345\236\213/04-CABI.kv" @@ -38,7 +38,11 @@ camelCase)——kvspace 层前缀 `kvspace`(`kvspaceGet` / `kvspaceWriteInPl `kvspaceDelTree` 对**最终组件**不解析 link——写/删 Ptr 键只作用该键本体,不重定向到 target (`Del`/`DelTree` 为 POSIX rm 式:删指针本身,不删被指向者)。解引用由 runtime 显式 `*` 掌控(见 [[ptr]])。否则「写实参地址 Ptr 到帧槽」会被重定向到 target,导致丢参 / 写坏被指向的值。 -## kvspace C ABI 导出符号全集(nm -D 实测,30) +## kvspace C ABI 导出符号(快照) + +权威来源是**构建产物**——`nm -D --defined-only /usr/lib/kvspace/libkvspace.so | grep '^kvspace'`(前端 +dispatch 静态导出;后端 `kvspace-c` / `kvspace-durable` 各导出同一集合)。下列快照仅作阅读导航,改 ABI 时 +不必同步本文: ``` kvspaceClear diff --git "a/stdlib/kvlang/spec/02-kvspace\346\250\241\345\236\213/05-\351\224\256\347\263\273\347\273\237\344\270\216\346\225\260\347\273\204\350\256\277\351\227\256.kv" "b/stdlib/kvlang/spec/02-kvspace\346\250\241\345\236\213/05-\351\224\256\347\263\273\347\273\237\344\270\216\346\225\260\347\273\204\350\256\277\351\227\256.kv" index cc27a2c0..d51424b7 100644 --- "a/stdlib/kvlang/spec/02-kvspace\346\250\241\345\236\213/05-\351\224\256\347\263\273\347\273\237\344\270\216\346\225\260\347\273\204\350\256\277\351\227\256.kv" +++ "b/stdlib/kvlang/spec/02-kvspace\346\250\241\345\236\213/05-\351\224\256\347\263\273\347\273\237\344\270\216\346\225\260\347\273\204\350\256\277\351\227\256.kv" @@ -29,18 +29,16 @@ kind 常量集中定义于 `kvspace/include/kvspace/const.h`(C)与 `kvspace- ### langtype 文法 -langtype 串**全前缀**书写,最左符号为最外层构造器,无优先级歧义(对齐 Go/Rust 的 `[]int`): - -``` -langtype ::= [ dims ] kind -dims ::= '[' ']' # 变长一维 - | '[' INT ( ',' INT )* ']' # 定长 / 多维(compact 连续布局) -``` +langtype 串**全前缀**书写,最左符号为最外层构造器,无优先级歧义(对齐 Go/Rust 的 `[]int`)。完整文法 +(shape 与轴量词 `.`/`?`/`*`/`+`、并集 `A|B`、通配 `any`、mapexpr `key·value`、structref)**只在附录 +[[文法]] 一处定义**,本章与其它卷只引用、不另立。 +**`langtype` 与 `def langtype` 是两回事**:值处写的是 `langtype`(值的**真实类型**),定义处(函数参数/返回 +值)写的是 `def langtype`(**匹配类型**)——后者是模式,**一个参数定义可匹配多种实际 `langtype`**(见 +[[langtype签名类型表达式]] 与 [[匹配语义与变参]])。 维数与各维长度编码进 langtype 串本身;ref(存储位置)已独立为 head 中的 ref u8 字段(见 [[XValueHead -线格式]]),不再是 langtype 前缀——storetype 物理字段携带对应的 ndim/dims 结构。完整签名类型表达式 -(并集 `A|B`、通配 `any`、动态维 `?`、map 键值 `key·value`)见 [[文法]] 与类型系统卷。**源码**类型标 -注可在最前写 `*`/`@` 前缀表示 ref(如 `*int64`、`@[256,256]uint8`),layout 解析时剥离前缀落成 head -`ref` 独立字节;wire 层 langtype 串不含 `*`/`@` 前缀(见 [[总体方案]])。 +线格式]]),不再是 langtype 前缀——storetype 物理字段携带对应的 ndim/dims 结构。**源码**类型标注可在最 +前写 `*`/`@` 前缀表示 ref(如 `*int64`、`@[256,256]uint8`),layout 解析时剥离前缀落成 head `ref` 独立 +字节;wire 层 langtype 串不含 `*`/`@` 前缀(见 [[总体方案]])。 "#### -> /lib/kvlang/spec/kvspace模型/键系统与数组访问 } diff --git "a/stdlib/kvlang/spec/02-kvspace\346\250\241\345\236\213/06-XValueHead\347\272\277\346\240\274\345\274\217.kv" "b/stdlib/kvlang/spec/02-kvspace\346\250\241\345\236\213/06-XValueHead\347\272\277\346\240\274\345\274\217.kv" index 2e5811b3..87360fa4 100644 --- "a/stdlib/kvlang/spec/02-kvspace\346\250\241\345\236\213/06-XValueHead\347\272\277\346\240\274\345\274\217.kv" +++ "b/stdlib/kvlang/spec/02-kvspace\346\250\241\345\236\213/06-XValueHead\347\272\277\346\240\274\345\274\217.kv" @@ -20,7 +20,7 @@ body = [body_len B raw] | `ro` | 1B | 1=只读,0=可写 | | `vid` | 4B LE | vthread id(默认 0) | | `body_len` | 4B LE | body 字节数 | -| (storetype 物理字段) | 变 | ARRAYND:ndim u8 + dims[ndim] u32 LE;index/extindex:成员名 m×n 对齐字符串数组 dims=[len,cap,M](len=成员数、M align8、cap 预留容量);主槽 body 恒空 | +| (storetype 物理字段) | 变 | ARRAYND:ndim u8 + dims[ndim] u32 LE;index/extindex:**成员枚举载体**(shm 载体为成员名 m×n 对齐字符串数组,dims=[len,cap,M],len=成员数、M align8、cap 预留容量;fs 载体把成员落成 `{key}·/` 子目录);值容器主槽 body 恒空、dims 空 | | `langtype` | 变长 | 类型表达式串,占至 `headlen`(长度 = headlen − 当前偏移,无独立长度字段) | `langtype` 恒为 head 最后一段,无独立长度字段;body 起始偏移 = `headlen`。ref 与 storetype 各为独立 @@ -28,6 +28,10 @@ u8 字节,不再编码进 langtype 串。ARRAYND 的 ndim、dims 直接读自 `[dims]` 保持同步(由 codec 保证)。`char/*` kind 恒为 ARRAYND(ndim=1)。None 编码: storetype=NONE、langtype=""、body 空。 +index/extindex 的**语义是"可枚举成员"**(`kvspaceListLen` / `kvspaceListAt`),物理载体按后端而异:shm 把 +成员名收进 head 的 m×n 矩阵,fs 把成员落成 `{key}·/` 子目录——载体差异经对称编解码还原,**不构成 ABI +语义差异**(见 [[地址空间]])。值容器(stringkeymap/struct)主槽只持类型与形状,成员在 `{key}·`。 + 指针(ref=1)的 head langtype = 目标完整 langtype(langtype,含 `[dims]`),storetype = 目标 storetype,body = 目标 key 路径;由 `kvspaceNewPtr(target_langtype, target)` 构造,Set 时据此单跳类 型检查。 diff --git "a/stdlib/kvlang/spec/02-kvspace\346\250\241\345\236\213/07-\346\225\260\347\273\204\344\270\244\347\247\215\347\211\251\347\220\206\345\275\242\346\200\201.kv" "b/stdlib/kvlang/spec/02-kvspace\346\250\241\345\236\213/07-\346\225\260\347\273\204\344\270\244\347\247\215\347\211\251\347\220\206\345\275\242\346\200\201.kv" index 796a4ce3..4298ab24 100644 --- "a/stdlib/kvlang/spec/02-kvspace\346\250\241\345\236\213/07-\346\225\260\347\273\204\344\270\244\347\247\215\347\211\251\347\220\206\345\275\242\346\200\201.kv" +++ "b/stdlib/kvlang/spec/02-kvspace\346\250\241\345\236\213/07-\346\225\260\347\273\204\344\270\244\347\247\215\347\211\251\347\220\206\345\275\242\346\200\201.kv" @@ -13,10 +13,11 @@ lib kvlang/spec/kvspace模型/数组两种物理形态 { ndim≥1。对齐 C `int[10]`、Go `[10]int`、Rust `[i32;10]`;多维即连续布局的 ndarray/tensor。要求元素 定长同类型——含变长字符串字面量的 `[…]` 在 layout 阶段报错。支持 `arr[i]` 随机访问(下标读经 `xv·at` 在 body 内定位),可零拷贝整块读。 -- **stringkeymap**:head kind=`stringkeymap`、ndim≥1,body 只记形状;每个元素是独立子 key,成员名为 - **坐标段**。变长、可增长、允许变长元素——字符串数组、可追加数组走此形态。stringkeymap **必须** - ndim≥1(无维度的键值容器应为 `struct`),且成员名**必须**是坐标段(`kvspace-durable/src/const.rs` - 的 `ERR_MAP_NDIM`、`ERR_MAP_COORD`)。 +- **stringkeymap**:head kind=`stringkeymap`、ndim≥1,body 只记形状;每个元素是独立子 key,成员名即 + **memitemkey 值逐字**(逐字铁律见 [[文法与合法性]]):裸标量键落 `b·200`、标量元组键落 + `a·[342.124,23.2345]`、字符串键落 `m·a`;由 `scatter` 展开的数组元素落坐标段 `base·[i]`。变长、可 + 增长、允许变长元素——字符串数组、可追加数组走此形态。stringkeymap **必须** ndim≥1(无维度的键值容器 + 应为 `struct`)。 ## 坐标段 @@ -57,7 +58,7 @@ stringkeymap 元素的成员名是坐标段,物理 key 形如 `m·[i]`(一 ref=2 表示值本体在扩展世界(SHM/GPU/文件),head 中 langtype 记录形态(如 `[256,256]uint8`),body 记位置描述符。@ext 只表**单个值**存于扩展世界(compact 形态),与 storetype=index/extindex 无关。读 -取时按 body 前缀路由兑现(见 [[地址空间]] 扩展存储)。 +取时由支持 `@` 的 rwir(如 runtime-rs 的 fs/networld 一族)按定位串兑现(见 [[地址空间]] 扩展存储)。 ## memindex:定宽目录矩阵 diff --git "a/stdlib/kvlang/spec/02-kvspace\346\250\241\345\236\213/08-\346\214\207\344\273\244\345\270\203\345\261\200\346\240\274\345\274\217.kv" "b/stdlib/kvlang/spec/02-kvspace\346\250\241\345\236\213/08-\346\214\207\344\273\244\345\270\203\345\261\200\346\240\274\345\274\217.kv" index f3f86653..dba05960 100644 --- "a/stdlib/kvlang/spec/02-kvspace\346\250\241\345\236\213/08-\346\214\207\344\273\244\345\270\203\345\261\200\346\240\274\345\274\217.kv" +++ "b/stdlib/kvlang/spec/02-kvspace\346\250\241\345\236\213/08-\346\214\207\344\273\244\345\270\203\345\261\200\346\240\274\345\274\217.kv" @@ -22,16 +22,18 @@ lib kvlang/spec/kvspace模型/指令布局格式 { ### 签名行 -函数目录 `/lib/{pkg}·{name}/` 自身(主槽):storetype = index、langtype = `rwfunc`(裸种类名,**不含 -签名**),body = `[nr:u16 LE][nw:u16 LE][dynamic:u8]`(读参个数 `nr`、写参个数 `nw`、是否变参 -`dynamic`)。 +函数目录 `/lib/{pkg}·{name}/` 自身是普通**目录节点**:storetype = index、langtype = `index`、**无值** +(body 空)。rwfunc 的**计数头**落签名行锚点 `/lib/{pkg}·{name}/[0,0]`——storetype = index、langtype = +`rwfunc`(裸种类名,**不含签名**),body = `[nr:u16 LE][nw:u16 LE][dynamic:u8]`(读参个数 `nr`、写参 +个数 `nw`、是否变参 `dynamic`)。 rwfunc 的各参数类型**不**落 `/[0,x]` 静态槽,而随**参数定义键**承载:`/lib/{pkg}·{name}.[0,-j]` (读参)/ `.[0,+j]`(写参)——点后缀、与坐标斜杠键 `/[0,±j]` 不同名——langtype `def langtype`, -body = 参数名 + NUL + 该参数完整类型串。参数顺序由键中的 `±j` 显式记录(命名键不保序),故 func 目录 +body = 参数名 + NUL + 该参数的 **def langtype**(匹配类型)串——一个参数定义可匹配多种值的 langtype。参 +数顺序由键中的 `±j` 显式记录(命名键不保序),故 func 目录 根**不**落 `/[0,x]` 子槽。 -`def rwir` 则相反:主槽 langtype = `def rwir`(裸种类名)、body 同计数格式,各参数类型落**位置化**签 +`def rwir` 则相反:`/lib/` 节点自身 langtype = `def rwir`(裸种类名)、body 同计数格式,各参数类型落**位置化**签 名 行 `[0,x]` 子槽(`x<0` 读参、`x>0` 写参,storetype=ATOM、langtype=`def langtype`,body 为该参数 langtype 串),无 `{param}` 命名键、无实现指令行——跨 runtime 队列按位置收参故须有序签名(见 [[总体方 @@ -42,18 +44,23 @@ langtype 串),无 `{param}` 命名键、无实现指令行——跨 runtime 以 `id_val(x:int64) -> (R:int64) { int64·add(x, 0) -> R }` 为例,`/lib/id_val/` 下: ``` -/lib/id_val/ storetype=index langtype=rwfunc body=[nr=1,nw=1,dyn=0] ← 主槽;langtype 裸种类名,不含签名 -[0,0] 签名行锚点(s0=0),body=[nr,nw,dyn] 计数头 -x ptr(langtype=int64)→"[0,-1]" ← 命名读参:body=坐标、langtype=该参类型 -R ptr(langtype=int64)→"[0,1]" ← 命名写参:body=坐标、langtype=该参类型 -[1,0] rwir:int64·add ← 指令0 opcode -[1,-1] rwir:x ← 指令0 读槽1 -[1,-2] int64:0 ← 指令0 读槽2(内联字面量) -[1,1] rwir:R ← 指令0 写槽1 +/lib/id_val/ storetype=index langtype=index ← 普通目录节点(无值) +[0,0] storetype=index langtype=rwfunc body=[nr,nw,dyn] ← 签名行锚点(s0=0),只记计数头 +.[0,-1] def langtype:"x\0int64" ← 参数定义键(点后缀):参数名 + NUL + def langtype 串 +.[0,1] def langtype:"R\0int64" ← 参数定义键(写参) +[1,0] storetype=ATOM langtype=rwir|rwfunc body=counts+"int64·add" ← 指令0 opcode +[1,-1] storetype=ATOM langtype=rwir body=counts+"[0,-1]" ← 指令0 读槽1(形参已换成帧坐标) +[1,-2] storetype=ATOM langtype=int64 body=raw(8B) ← 指令0 读槽2(内联字面量,非 rwir、无 counts) +[1,1] storetype=ATOM langtype=rwir body=counts+"[0,1]" ← 指令0 写槽1 ``` -opcode 槽 langtype 为 `rwir`(可为 `rwfunc` 引用),body 记 opcode 名。读/写槽的值有两类: -`rwir:name` 是对变量的引用(存名字文本,即相对指针),或内联字面量(如 `int64:0`、 -`char/utf32:"…"`)。opcode 槽永不存变量引用,故值拷贝 `=` 与函数调用 `call` 在 KV 层无歧义。 +opcode 槽 langtype 为 `rwir|rwfunc`——这是**派发标记**(layout 不静态判定目标是 runtime 兑现的 rwir 还 +是用户 rwfunc,判定推迟到 runtime 查 `/lib/`,见 [[指令槽编码]]),非值语言类型。 + +**`rwir` 值的 body 格式(唯一)**:`counts` = `[nr:u16 LE][nw:u16 LE][dynamic:u8]`(5 字节,指令槽恒 +`0,0,0`)+ 槽文本;文本是 opcode 名,或变量引用(相对指针 `[0,±k]`)。**内联字面量不是 `rwir`**——按字 +面量自身的 kind 编码(如 `int64` 的 8 字节 raw),**无** `counts`。故读/写槽的值两类:`rwir`(counts + +文本)或内联字面量(如 `int64raw`、`char/utf32` 串)。opcode 槽永不存变量引用,故值拷贝 `=` 与函数调用 +`call` 在 KV 层无歧义。 "#### -> /lib/kvlang/spec/kvspace模型/指令布局格式 } diff --git "a/stdlib/kvlang/spec/02-kvspace\346\250\241\345\236\213/09-\350\260\203\347\224\250extindex.kv" "b/stdlib/kvlang/spec/02-kvspace\346\250\241\345\236\213/09-\350\260\203\347\224\250extindex.kv" index dab5f598..d40af78a 100644 --- "a/stdlib/kvlang/spec/02-kvspace\346\250\241\345\236\213/09-\350\260\203\347\224\250extindex.kv" +++ "b/stdlib/kvlang/spec/02-kvspace\346\250\241\345\236\213/09-\350\260\203\347\224\250extindex.kv" @@ -6,9 +6,10 @@ lib kvlang/spec/kvspace模型/调用extindex { 令树的 extindex 叠加层,再把实参 / 结果地址写进帧根下的 `[0,±j]` 槽: - `/lib/{pkg}·{name}.[0,±j]`(rwfunc 的**参数定义键**,点后缀、与坐标斜杠键 `/[0,±j]` 不同名): - langtype=`def langtype`,body=该参数名字 + NUL + 类型串。此键是**签名元数据**(dump / 类型检查 - 用),**不参与运行时形参解析**;函数体指令里的形参引用已在 layout 编译期替换为帧坐标的显式解引用 - `*[0,-1]`。目录根**无** `/[0,±j]` 静态坐标槽——运行时向 `frameRoot/[0,±j]` 写实参地址 Ptr 时, + langtype=`def langtype`,body=该参数名字 + NUL + **def langtype**(匹配类型)串。此键是**签名元数据**(dump / 类型检查 + 用),**不参与运行时形参解析**;函数体指令里的形参引用已在 layout 编译期替换为帧坐标(值参 `[0,-1]` + 直读,地址参 `*[0,-1]` 解引用,见 [[函数]])。目录根**无** `/[0,±j]` 静态坐标槽——运行时向 + `frameRoot/[0,±j]` 写实参槽时, 该坐标在只读 extindex 目标(函数树)中并不存在,extindex 写保护正因**该名在扩展层缺席而放行**帧本 地写,实参内容零拷贝。(反之若 layout 预落 `/[0,±j]` 静态槽,写保护会因扩展层已有同名只读节点而拒 写、丢参——故 rwfunc 目录根不落这些坐标。) @@ -16,20 +17,22 @@ lib kvlang/spec/kvspace模型/调用extindex { 崩溃恢复由此自然成立:PC 是路径字符串、帧根落 KV、返回点落 KV——进程重启后可从 kvspace 续跑。 -## 参数解析:一层引用(显式解引用) +## 参数解析:值参直读、地址参一层引用 -函数体指令里的形参引用,layout 编译期把参数名替换为**对帧槽坐标的显式解引用** `*[0,-1]`。帧槽 -`frameRoot/[0,-1]` 由调用点写入实参地址 Ptr(ref=1,langtype=参数类型,body=实参地址),`*` 解引用 -一次即得实参真实值: +layout 编译期把形参名替换为**帧槽坐标** `[0,-k]`(值参)或**对帧槽坐标的解引用** `*[0,-k]`(地址参,即 +声明带 `*`/`@`;见 [[函数]])。两种帧槽由调用点写入(见 [[函数调用]]): ``` -1. frameRoot/[0,-1] → 实参 key 路径 槽 → 实参地址(调用点写入的帧本地 Ptr) -2. *[0,-1] → 值 显式解引用一次 +值参 x:T :frameRoot/[0,-k] → 值本体(本帧副本) 体内 [0,-k] 只读(param<0 只读) +地址参 p:*T :frameRoot/[0,-k] → 实参 key 路径 Ptr 体内 *[0,-k] 解引用取实参值 +扩展参 h:@T :frameRoot/[0,-k] → 扩展世界定位串(ref=2)由支持 @ 的 rwir 兑现(如 runtime-rs 的 fs/networld 族) ``` -读写对称:读参 `*[0,-k]` 读到实参值;写参 `*[0,+k]` 指回调用者写槽,子帧写参直写调用方目标位置。读参 -地址可指向调用方值以实现零拷贝重定向(见 [[系统变量]] 的 `‥rparam` / `‥wparam`)。形参类型随帧槽的 -Ptr langtype 承载,不在解析链上额外查参数定义键。 +**读参(`param<0`)一律只读**:值读参的槽是本帧副本、地址读参 `*[0,-k]` 读到实参值,两者都不得作写槽。 +**写参(`param>0`)可读可写**:地址写参 `*[0,+k]` 直写调用方目标位置;值写参按 [[系统变量]] 的 `‥wdst` +表 copy-in / copy-out。`@` 参数的帧槽是扩展定位串——runtime-c 不可直达,读它须按定位串前缀由支持 `@` 的 +rwir(在支持它的 runtime 里,如 runtime-rs 的 fs/networld 一族)按 head 的 ref=2 定位串兑现(见 +[[ref存储位置]])。形参类型随帧槽的 XValue langtype 承载,不在解析链上额外查参数定义键。 写侧关键约束:kvspace 对 Set/Del **不穿透整键**(Ptr 键的写/删只作用该键本身,不追 target)——自动 穿透会把「写实参地址 Ptr 到帧槽」重定向到 target,导致丢参 / 写坏被指向的值。解引用一律由 runtime 显 diff --git "a/stdlib/kvlang/spec/02-kvspace\346\250\241\345\236\213/10-\347\263\273\347\273\237\345\217\230\351\207\217.kv" "b/stdlib/kvlang/spec/02-kvspace\346\250\241\345\236\213/10-\347\263\273\347\273\237\345\217\230\351\207\217.kv" index 2260695e..f7f31cb5 100644 --- "a/stdlib/kvlang/spec/02-kvspace\346\250\241\345\236\213/10-\347\263\273\347\273\237\345\217\230\351\207\217.kv" +++ "b/stdlib/kvlang/spec/02-kvspace\346\250\241\345\236\213/10-\347\263\273\347\273\237\345\217\230\351\207\217.kv" @@ -16,9 +16,8 @@ lib kvlang/spec/kvspace模型/系统变量 { | 键 | 语义 | |----|------| | `‥pc` | 当前执行 PC(绝对路径字符串) | -| `‥status` | 运行状态:`init` / `running` / `wait` / `paused`;进入终态时删除并 Notify 返回值 | +| `‥status` | 运行状态:`init` / `running` / `wait` / `paused` / `error`;**终态写入的是返回值串**(默认 `"ok"`)并 Notify | | `‥status/msg` | 状态附带消息;错误时形如 `‥error/msg` 承载错误文本 | -| `‥debugger` | 调试控制:空为正常,`paused` 为暂停;`debugger()` 内建写此键 | | `‥ctime` | 创建时刻 | ## 帧系统变量 @@ -31,7 +30,6 @@ lib kvlang/spec/kvspace模型/系统变量 { | `‥lib` | rwfunc 帧的 lib 路径,用于识别 rwfunc 帧边界 | | `‥callpc` | 帧内执行进度(每 op 更新;块帧重入亦更新) | | `‥returnpc` | 返回地址(帧创建时固化;块帧仅首次设置,重入不覆写) | -| `‥ro` | 只读参数名单,写槽检查用 | | `‥wdst` | **值写参的目标表**(仅当本帧有值写参时落):每行一个写参的调用方目标 key,行序即写参槽序,地址写参留空行。返回时据此 copy-out | **值写参的 copy-in / copy-out**(见 [[函数]]):调用点把调用方该位置的当前值**复制**进帧槽 @@ -46,15 +44,16 @@ runtime 按 `‥wdst` 把 `[0,+k]` **复制回**目标。地址写参(声明 具名作用域的标签不落在帧上,而落在函数的 `/lib` 定义处:`/lib/{pkg}·{name}/‥labels/{label}` → 指令序 号(`layout/src/keytree.rs`、`layout/src/code.rs`)。 -## 语法层保留名 `._` +## 丢弃槽 `_` -`._` 是源码层的丢弃槽占位符:写目标为 `._` 时不落 kvspace(帧槽键构造遇此名返回空路径)。它是语法占 -位符,**不**是 `‥` 系统变量,不落入 kvspace。 +写槽写 `_` 即丢弃该位置(见 [[指令架构]]):它是普通裸名,落帧内 `_` 槽。runtime 内部另为字面量实参建 +`._litN` 临时槽(见 [[函数调用]]),与丢弃槽无关、也不属 `‥` 系统变量命名空间。 ## `debugger()` `debugger()` 内建对齐 V8/TypeScript 的 `debugger;` 语句:源码内联暂停点。非调试模式下为 no-op;调试 -模式下将 `‥status` 置 `paused`,由外部驱动改回 `running` 恢复执行。 +模式下将 `‥status` 置 `paused`,由外部驱动改回 `running` 恢复执行——**暂停能力就是 `‥status=paused`** +(`debugger()` ≡ `vthread·setstatus("paused")`),**不会另设** `‥debugger` 之类的独立系统变量。 ## 域与变量之别 diff --git "a/stdlib/kvlang/spec/03-\347\261\273\345\236\213\347\263\273\347\273\237/01-\347\247\215\347\261\273\344\270\216\345\256\232\345\256\275\347\261\273\345\236\213.kv" "b/stdlib/kvlang/spec/03-\347\261\273\345\236\213\347\263\273\347\273\237/01-\347\247\215\347\261\273\344\270\216\345\256\232\345\256\275\347\261\273\345\236\213.kv" index ce7b28eb..48582dc4 100644 --- "a/stdlib/kvlang/spec/03-\347\261\273\345\236\213\347\263\273\347\273\237/01-\347\247\215\347\261\273\344\270\216\345\256\232\345\256\275\347\261\273\345\236\213.kv" +++ "b/stdlib/kvlang/spec/03-\347\261\273\345\236\213\347\263\273\347\273\237/01-\347\247\215\347\261\273\344\270\216\345\256\232\345\256\275\347\261\273\345\236\213.kv" @@ -18,7 +18,7 @@ kvlang 是**严格定宽类型语言**。 - 字符编码与索引:`tutorial/11-string/05-encodings.kv`、`06-convert.kv`、`02-char-ord.kv`。 - 时间种类:`tutorial/01-basics/time.kv`、`tutorial/13-stdlib/time/`、`13-stdlib/duration/`。 - 类型错误(bool 算术、跨种类比较、无符号取负、None、compact 变长串): - `tutorial/error_cases/type_error/`、`error_cases/none_type_error/`。 + `error_cases/type_error/`、`error_cases/none_type_error/`。 ## 数值运算域 diff --git "a/stdlib/kvlang/spec/03-\347\261\273\345\236\213\347\263\273\347\273\237/02-\347\247\215\347\261\273-\346\240\207\351\207\217\346\227\266\351\227\264\345\256\271\345\231\250.kv" "b/stdlib/kvlang/spec/03-\347\261\273\345\236\213\347\263\273\347\273\237/02-\347\247\215\347\261\273-\346\240\207\351\207\217\346\227\266\351\227\264\345\256\271\345\231\250.kv" index c0ca255d..8a794165 100644 --- "a/stdlib/kvlang/spec/03-\347\261\273\345\236\213\347\263\273\347\273\237/02-\347\247\215\347\261\273-\346\240\207\351\207\217\346\227\266\351\227\264\345\256\271\345\231\250.kv" +++ "b/stdlib/kvlang/spec/03-\347\261\273\345\236\213\347\263\273\347\273\237/02-\347\247\215\347\261\273-\346\240\207\351\207\217\346\227\266\351\227\264\345\256\271\345\231\250.kv" @@ -51,14 +51,14 @@ kvlang 的数字种类**必须携带精确位宽**: 必须**报 TypeError。单个字符标注为 `char/<编码>`(标量),字符串标注为 `[]char/<编码>`(序列);字符 种类的值恒为一维序列。 -### 容器与结构种类 - -| 种类 | 说明 | -|------|------| -| `stringkeymap` | map 容器,langtype 为 `key·value`(如 `[]char/utf8·int64`) | -| `struct` | 结构原型实例的种类(见 [[struct]]) | -| `index` | **storetype**:索引型节点(map/struct 值容器的 `{key}·` memindex、lib/rwfunc 目录节点);物理=m×n 对齐字符串数组,dims=[len,cap,M](M align8) | -| `extindex` | **storetype**:可扩展索引型节点(vthread 运行栈等,cap 可增长);与 `ref`/`@ext` 无关,extindex 是 storetype 不是 ref=2 | +### 容器与结构 + +| 名 | 性质 | 说明 | +|----|------|------| +| `stringkeymap` | 种类(kind) | map 容器,langtype 为 `key·value`(如 `[]char/utf8·int64`) | +| `struct` | 种类(kind) | 结构原型实例的种类(见 [[struct]]) | +| `index` | **storetype**(非 kind) | 索引型节点(map/struct 值容器的 `{key}·` memindex、lib/rwfunc 目录节点);成员枚举载体 | +| `extindex` | **storetype**(非 kind) | 可扩展索引型节点(vthread 运行栈等,cap 可增长);与 `ref=2`(@ext) 无关 | 容器的物理组成(值 + memindex)见 [[map容器]](struct 同此物理模型)。 diff --git "a/stdlib/kvlang/spec/03-\347\261\273\345\236\213\347\263\273\347\273\237/03-\347\247\215\347\261\273-\344\273\243\347\240\201\344\270\216\347\211\271\346\256\212\345\200\274.kv" "b/stdlib/kvlang/spec/03-\347\261\273\345\236\213\347\263\273\347\273\237/03-\347\247\215\347\261\273-\344\273\243\347\240\201\344\270\216\347\211\271\346\256\212\345\200\274.kv" index 9329262f..ac23f00c 100644 --- "a/stdlib/kvlang/spec/03-\347\261\273\345\236\213\347\263\273\347\273\237/03-\347\247\215\347\261\273-\344\273\243\347\240\201\344\270\216\347\211\271\346\256\212\345\200\274.kv" +++ "b/stdlib/kvlang/spec/03-\347\261\273\345\236\213\347\263\273\347\273\237/03-\347\247\215\347\261\273-\344\273\243\347\240\201\344\270\216\347\211\271\346\256\212\345\200\274.kv" @@ -6,8 +6,8 @@ lib kvlang/spec/类型系统/种类_代码与特殊值 { 下列 langtype 描述 KV 树中的代码与目录节点(见 [[指令布局格式]]): -- `rwir`:无 kvlang 实现体,指令名文本,storetype=ARRAYND 叶子;由 runtime 经 def rwir 路由直接兑 - 现。 +- `rwir`:无 kvlang 实现体,storetype=ATOM,body = `[nr:u16 LE][nw:u16 LE][dynamic:u8]`(指令槽恒 + `0,0,0`)+ 指令名/引用文本;由 runtime 经 def rwir 路由直接兑现。 - `def rwir`:**路由头**,仅存于 `/lib/`,是 rwir 统一调度入口,storetype=index(定义节点),** 无 kvlang 实现体**;**不叫"扩展算子"**,**不得**出现在用户书写的类型标注中。每个 runtime 只声明 **myrwircaps**(该 runtime 能兑现的 rwir 能力集);rwir 若不在本 runtime myrwircaps 内须经 diff --git "a/stdlib/kvlang/spec/03-\347\261\273\345\236\213\347\263\273\347\273\237/05-langtype\347\255\276\345\220\215\347\261\273\345\236\213\350\241\250\350\276\276\345\274\217.kv" "b/stdlib/kvlang/spec/03-\347\261\273\345\236\213\347\263\273\347\273\237/05-langtype\347\255\276\345\220\215\347\261\273\345\236\213\350\241\250\350\276\276\345\274\217.kv" index bc74544f..c1af27fe 100644 --- "a/stdlib/kvlang/spec/03-\347\261\273\345\236\213\347\263\273\347\273\237/05-langtype\347\255\276\345\220\215\347\261\273\345\236\213\350\241\250\350\276\276\345\274\217.kv" +++ "b/stdlib/kvlang/spec/03-\347\261\273\345\236\213\347\263\273\347\273\237/05-langtype\347\255\276\345\220\215\347\261\273\345\236\213\350\241\250\350\276\276\345\274\217.kv" @@ -1,42 +1,47 @@ // 欢迎加入kvspace世界 lib kvlang/spec/类型系统/langtype签名类型表达式 { - r####"# langtype(两型与 kindexpr) + r####"# langtype 与 def langtype(定义处的匹配类型) **langtype** 是 XValue head 的语义类型维(见 [[总体方案]]、[[head字段]]),逐字节是一段**类型表达式 串**——base 种类、可选形状 `[dims]`、mapexpr、原型路径等(文法见 [[文法与合法性]])。它既供人和工具读 写,也落入 kvspace 作运行期匹配依据,贯穿 layout(静态校验)与 runtime(值匹配),是类型的唯一真相。 -## langtype 两型:def langtype 与 value langtype +## langtype 与 def langtype -同一套文法,按**角色**分两型: +**langtype 是值的真实类型;def langtype 是定义函数时参数/返回值的匹配类型。** 两者同吃一套文法(附录 +[[文法]]),但角色与表达力不同: -| 型 | 出现位置 | 角色 | 表达力 | +| | 出现位置 | 角色 | 表达力 | |----|---------|------|--------| -| **def langtype** | def rwir 签名行 `[0,x]` 槽(storetype=`def langtype`);rwfunc 则随参数定义键 `.[0,±j]`(body=名字+NUL+类型串)承载同一模式(见 [[storetype_def族与签名行]]) | **模式**:描述一个参数「可接受的一类值」 | 完整——并集 `A\|B`、轴量词 `.`/`?`/`*`/`+`、`any`、mapexpr(见 [[匹配语义与变参]])。参数变参 `...` 是签名层 arity、**不在** langtype 内(见 [[函数]]) | -| **value langtype** | 一个具体 XValue 的 head langtype(见 [[langtype语义类型]]) | **实例**:描述这个值**是什么** | 具体固定——单一种类 + 确定 `[dims]`(每维具体整数),不含并集与任何轴量词 | +| **langtype** | 一个具体 XValue 的 head langtype(见 [[langtype语义类型]]) | 值**是什么**:一个具体实例的类型 | 具体固定——单一种类 + 确定 `[dims]`(每维具体整数),**不含**并集与任何轴量词 | +| **def langtype** | 函数定义处——`def rwir` 的签名行 `[0,x]` 槽、`rwfunc` 的参数定义键 `.[0,±j]`(承载节点的 head langtype 都是 `def langtype`,见 [[storetype_def族与签名行]]) | 参数**可接受的一类值**:**匹配类型** | 完整——并集 `A\|B`、轴量词 `.`/`?`/`*`/`+`、`any`、mapexpr(见 [[匹配语义与变参]]) | -def langtype 是「值域」,value langtype 是值域里「一个点」;类型检查即判定后者是否落进前者(匹配语义 -见 [[匹配语义与变参]])。 +**一个 def langtype 可匹配多种 langtype**——这正是参数多态的来源:`x:int8|int16|int32|int64` 接受四种整数, +`a:[.,*]float32` 接受首维任意、秩 ≥1 的 float32 数组,`v:any` 接受一切。装载与调用时,把**实参值的 +langtype** 对参数定义的 **def langtype** 逐值判定:命中即通过,失配报 TypeError(见 [[匹配语义与变参]])。 +参数变参 `...` 是签名层 arity 构造,**不在** def langtype 串内(见 [[函数]])。 + +**唯一例外**是 opcode 槽 `[s0,0]` 的 `rwir|rwfunc`——它是**派发标记**(layout 不静态判定目标是 rwir 还是 +rwfunc,交 runtime 查 `/lib/` 定,见 [[指令槽编码]]),既不是值类型、也不属 def langtype。 ## kindexpr(简写) -一段**具体的 langtype 串**——无论是某个 value 的 langtype,还是某条 def 签名里某参数的 langtype——统称 -**kindexpr**。故 kindexpr 与 langtype 指同一文法产物:`langtype` 强调 head 的语义类型维,`kindexpr` -强调「一条具体的类型表达式串」。def langtype 是允许模式构造(并集 `|` 与轴量词 `.`/`?`/`*`/`+`)的 -kindexpr,value langtype 是不含模式构造的 kindexpr。下文与各卷凡书「kindexpr」即指一条具体 langtype -串。 +一条**类型表达式串**——无论写在值处(`langtype`)还是定义处(`def langtype`)——统称 **kindexpr**。故三者 +同文法、只差角色:`langtype` 强调「值的真实类型」,`def langtype` 强调「定义处的匹配类型」,`kindexpr` 强 +调「一条具体的类型表达式串」。下文与各卷凡书「kindexpr」即指一条类型表达式串。 ## 两条 runtime-c ABI(供外部调用) -runtime-c 对外开放两组 langtype 能力,一一对应两型(`kvlang_myrwir.h` 与正典 codec,见 [[cruntime与 -后端abi]]),供扩展运行时与嵌入方调用: +runtime-c 对外开放两组类型能力,一一对应这两者(`kvlang_rwirext.h` 与正典 codec,见 [[cruntime与后端 +abi]]),供扩展运行时与嵌入方调用: -- **模式侧(def langtype)**:`LangtypeValid` 校验一条 def kindexpr 合法、`LangtypeMatch` 把一个值的 - `(kind,ndim,dims)` 对一条 def kindexpr 作**逐值无状态**模式匹配。用于签名校验与派发(参数变参判定 - 不在此,靠主槽 `dynamic` 字节,见 [[函数]])。 -- **具体侧(value langtype)**:把一条具体 kindexpr 解析/解码为 `(kind, ndim, dims, 元素字节宽)`——唯 - 一事实源为正典 codec `kvspaceDecodeHead`(读 head 的 value langtype)与 layout 的 - `kvlangLangtypeParse`(见 [[layout流水线接口]])。用于零拷贝定位、显示、round-trip。 +- **def langtype 侧(匹配)**:`LangtypeValid` 校验一条 def langtype 串合法、`LangtypeMatch` 把一个值的 + `(kind,ndim,dims)` 对一条 def langtype 作**逐值无状态**匹配。用于签名校验与派发(参数变参判定不在此, + 靠签名行锚点 `[0,0]` 的 `dynamic` 字节,见 [[函数]])。 +- **langtype 侧(解析)**:把一条 langtype 串解析/解码为 `(kind, ndim, dims, 元素字节宽)`——唯一事实源为 + 正典 codec `kvspaceDecodeHead`(读 head 的 langtype)与 `kvlangKindexprParse`(layout 侧入口;runtime 侧 + 同一能力名为 `kvlangLangtypeParse`,两处 ABI 名待统一,见 [[layout流水线接口]])。用于零拷贝定位、显 + 示、round-trip。 两 ABI 同源同文法(都吃一条 kindexpr 串),差别只在角色:**模式匹配** vs **具体解析**。runtime-c ** 不得**为二者各造一份编解码——文法与 codec 只此一处。 diff --git "a/stdlib/kvlang/spec/03-\347\261\273\345\236\213\347\263\273\347\273\237/06-\345\275\222\345\261\236\344\270\216\345\255\230\345\202\250.kv" "b/stdlib/kvlang/spec/03-\347\261\273\345\236\213\347\263\273\347\273\237/06-\345\275\222\345\261\236\344\270\216\345\255\230\345\202\250.kv" index 6fc243ad..61a5cc28 100644 --- "a/stdlib/kvlang/spec/03-\347\261\273\345\236\213\347\263\273\347\273\237/06-\345\275\222\345\261\236\344\270\216\345\255\230\345\202\250.kv" +++ "b/stdlib/kvlang/spec/03-\347\261\273\345\236\213\347\263\273\347\273\237/06-\345\275\222\345\261\236\344\270\216\345\255\230\345\202\250.kv" @@ -8,18 +8,25 @@ lib kvlang/spec/类型系统/归属与存储 { | def rwir 路由头 | `/lib/` | `def rwir` | | native 算子签名 | C 注册表(不落入 kvspace) | —— | -**铁律**:`rwfunc` 每个参数落入 kvspace 的 langtype 与源码里的类型标注**逐字节相同**(同一文法,含 -`...`);`def rwir` 源码不声明,其参数 langtype 由各 runtime 注册时按同一文法写入。签名**不写进 -langtype 串**,也不塞进主槽 body,分两处存(详见 [[总体方案]]「签名不入 langtype 串」): +**铁律**:`rwfunc` 每个参数落入 kvspace 的 **def langtype**(参数定义键 body 的类型串,即定义处的匹配类 +型)与源码里的类型标注**逐字节相同**(同一文法;变参尾缀 `...` 除外——它是签名层 arity、解析时剥离,见 +[[函数]]);`def rwir` 源码不声明,其参数 def langtype 由各 runtime 注册时按同一文法写入。签名**不写 +进**计数头节点的 langtype、也不塞进其 body,分两处存: -1. **主槽计数头**:主槽(如 `/lib/pkg·funca`)body 只记 `[nr:u16 LE][nw:u16 LE][dynamic:u8]`——读参个 - 数 `nr`、写参个数 `nw`、是否变参 `dynamic`(末位读参 `...`);**不含任何参数 langtype 串**。 -2. **签名行 `[0,x]` 各槽**:每个参数的 langtype 串落在签名行坐标 `[0,x]`(`x<0` 读参、`x>0` 写参、 - `[0,0]` 签名行锚点),每槽为一个 `def langtype` 类型的 xvalue,body 存该参数完整 langtype 串。 +1. **计数头**:`rwfunc` 落 `/lib/pkg·funca/[0,0]`(langtype `rwfunc`)、`def rwir` 落 `/lib/` 节点自 + 身(langtype `def rwir`),body 只记 `[nr:u16 LE][nw:u16 LE][dynamic:u8]`——读参个数 `nr`、写参个数 + `nw`、是否变参 `dynamic`(末位读参 `...`);**不含任何参数 langtype 串**。 +2. **参数类型承载**(按符号分两路,见 [[storetype_def族与签名行]]): + - `def rwir` → **位置化签名行 `[0,x]`**(`x<0` 读参、`x>0` 写参、`[0,0]` 锚点),每槽 `def langtype`, + body = 该参数完整 langtype 串(跨 runtime 队列按位置收参,故须有序)。 + - `rwfunc` → **参数定义键 `funcDir.[0,±j]`**(点后缀,与坐标斜杠键 `/[0,±j]` 不同名),每键 + `def langtype`,body = 参数名 + NUL + 类型串;函数体形参引用改走帧坐标,运行期不查此键(见 + [[调用extindex]])。 -故 rwfunc/def rwir 主槽的 langtype 就是裸种类名 `rwfunc`/`def rwir` 本身,不再是「签名 langtype -串」。native 算子的 langtype 内联在 C 注册表中,是唯一权威来源,运行时匹配**直接读 C 表、不回查 -kvspace**;数值多类型算子在 C 表中融合为单条(如 `add(a:int8|…|float64, b:…)`)。 +故计数头节点的 langtype 就是裸种类名 `rwfunc`(rwfunc 的 `[0,0]`)/`def rwir`(def rwir 的 +`/lib/` 节点自身)本身,不再是「签名 langtype 串」。native 算子的 langtype 内联在 C 注册表中,是唯 +一权威来源,运行时匹配**直接读 C 表、不回查 kvspace**;数值多类型算子在 C 表中融合为单条(如 +`add(a:int8|…|float64, b:…)`)。 ## 强制类型标注 diff --git "a/stdlib/kvlang/spec/03-\347\261\273\345\236\213\347\263\273\347\273\237/07-\346\226\207\346\263\225\344\270\216\345\220\210\346\263\225\346\200\247.kv" "b/stdlib/kvlang/spec/03-\347\261\273\345\236\213\347\263\273\347\273\237/07-\346\226\207\346\263\225\344\270\216\345\220\210\346\263\225\346\200\247.kv" index c7e4cc5a..c9484ba6 100644 --- "a/stdlib/kvlang/spec/03-\347\261\273\345\236\213\347\263\273\347\273\237/07-\346\226\207\346\263\225\344\270\216\345\220\210\346\263\225\346\200\247.kv" +++ "b/stdlib/kvlang/spec/03-\347\261\273\345\236\213\347\263\273\347\273\237/07-\346\226\207\346\263\225\344\270\216\345\220\210\346\263\225\346\200\247.kv" @@ -56,9 +56,11 @@ lib kvlang/spec/类型系统/文法与合法性 { > 轴量词 `.`/`?`/`*`/`+` 与正则一致,**只描述单个值的形状**。而**参数变参**(一个参数位吸收 0..N 个 实参,旧写法末读参尾缀 `...`)是**签名**层的 arity 构造,**不属于类型表达式**,见 [[函数]];它落成 - 函数主槽的 `dynamic` 字节,参数 langtype 子槽保持纯净(不含 `...`)。 + 签名行锚点 `[0,0]` 的 `dynamic` 字节,参数 langtype 子槽保持纯净(不含 `...`)。 -**合法性校验**(layout 与 runtime 一致):每个 atom 的基须为 `known` 种类名或 `any`;键须为 +**合法性校验**(layout 与 runtime 一致):每个 atom 的基须为 `known` 种类名、`any`,或**已声明的 +struct 原型路径**(`/lib/`)。裸标识符只有在能解析为 struct 原型时才可作 atom ——拼错的种类名 +(如 `intg64`)、家族简写(`int` 等)**必须**按非法种类拒绝,**不得**静默当成 structref 放行。键须为 `[]char/<编码>` 或全标量元组。非法示例及拒因: | 非法 | 拒因 | diff --git "a/stdlib/kvlang/spec/03-\347\261\273\345\236\213\347\263\273\347\273\237/08-\345\214\271\351\205\215\350\257\255\344\271\211\344\270\216\345\217\230\345\217\202.kv" "b/stdlib/kvlang/spec/03-\347\261\273\345\236\213\347\263\273\347\273\237/08-\345\214\271\351\205\215\350\257\255\344\271\211\344\270\216\345\217\230\345\217\202.kv" index d2398167..2ebbbe50 100644 --- "a/stdlib/kvlang/spec/03-\347\261\273\345\236\213\347\263\273\347\273\237/08-\345\214\271\351\205\215\350\257\255\344\271\211\344\270\216\345\217\230\345\217\202.kv" +++ "b/stdlib/kvlang/spec/03-\347\261\273\345\236\213\347\263\273\347\273\237/08-\345\214\271\351\205\215\350\257\255\344\271\211\344\270\216\345\217\230\345\217\202.kv" @@ -2,10 +2,10 @@ lib kvlang/spec/类型系统/匹配语义与变参 { r####"# 匹配语义与变参 -本章匹配语义作用于 **def langtype**(模式):把一个值的 value langtype `(kind,ndim,dims)` 与签名里的 -def langtype 判定是否命中(两型见 [[langtype签名类型表达式]])。匹配**恒逐值、无状态**:只看单个值, -不在参数间携带任何环境(跨操作数的维相等/输出推断不在类型层,归 op 的 shape function,见 [[runtimec内 -建]])。 +本章匹配语义作用于 **def langtype**(定义处的匹配类型):把一个值的 **langtype** `(kind,ndim,dims)` 与签名 +里的 def langtype 判定是否命中(两者区别见 [[langtype签名类型表达式]])。匹配**恒逐值、无状态**:只看单个 +值,不在参数间携带任何环境(跨操作数的维相等/输出推断不在类型层,归 op 的 shape function,见 +[[runtimec内建]])。 ## 匹配语义 @@ -36,10 +36,9 @@ def langtype 判定是否命中(两型见 [[langtype签名类型表达式]]) ## 参数变参(签名层,非类型) 一个**参数位**吸收 0..N 个同型实参(`print`/`println`/`min`/`max` 等 arity 开放算子)是**签名**的 -arity 属性,**不属于类型表达式**——源码在末读参尾缀 `...` 声明,由签名解析器剥离,落成函数主槽的 -`dynamic` 字节,该参数 langtype 子槽保持纯净(见 [[函数]]、[[指令布局格式]])。派发时:主槽 -`dynamic=1` → 末读参对**每个**尾随实参按其(纯净)langtype 逐个判定。`LangtypeValid`/`LangtypeMatch` -永不见 `...`。 +arity 属性,**不属于类型表达式**——源码在末读参尾缀 `...` 声明,由签名解析器剥离,落成签名行锚点 `[0,0]` +的 `dynamic` 字节,该参数 langtype 子槽保持纯净(见 [[函数]]、[[指令布局格式]])。派发时:`dynamic=1` → +末读参对**每个**尾随实参按其(纯净)langtype 逐个判定。`LangtypeValid`/`LangtypeMatch` 永不见 `...`。 XValue head 三正交维编码见 [[总体方案]](本卷只界定 langtype 串的文法与匹配语义)。 diff --git "a/stdlib/kvlang/spec/03-\347\261\273\345\236\213\347\263\273\347\273\237/09-\346\225\260\347\273\204\345\275\242\346\200\201.kv" "b/stdlib/kvlang/spec/03-\347\261\273\345\236\213\347\263\273\347\273\237/09-\346\225\260\347\273\204\345\275\242\346\200\201.kv" index ca8db7f9..01659bd0 100644 --- "a/stdlib/kvlang/spec/03-\347\261\273\345\236\213\347\263\273\347\273\237/09-\346\225\260\347\273\204\345\275\242\346\200\201.kv" +++ "b/stdlib/kvlang/spec/03-\347\261\273\345\236\213\347\263\273\347\273\237/09-\346\225\260\347\273\204\345\275\242\346\200\201.kv" @@ -16,14 +16,14 @@ kvlang 的数组有**两种物理形态**:**compact**(稠密:全量元素 - stringkeymap 字面量与遍历:`tutorial/04-ndarray/sparse_literal.kv`、`string_array.kv`。 - 两形态互转:`tutorial/04-ndarray/separated.kv`。 - 多值坐标段:`tutorial/04-ndarray/geo_coord.kv`。 -- 括号规约错误(compact 容变长串):`tutorial/error_cases/type_error/compact_string_array.kv`。 +- 括号规约错误(compact 容变长串):`error_cases/type_error/compact_string_array.kv`。 ## 括号规约 | 字面量 | 形态 | 落库 | 约束 | |--------|------|------|------| | `[e0, e1, …]` | compact | 元素连续打包进单个 XValue,head 的 langtype(langtype)= 元素种类(如 `[4]int64`),storetype=ARRAYND | 定长、同种类;元素**不得**为变长(字符串字面量禁入) | -| `{v0, v1, …}` | stringkeymap | 每元素落 `base·i` 独立子 key,容器值 langtype=map langtype(如 `[]char/utf8·int64`),storetype=index,主槽 body 空,成员名索引落 `base·` memindex(m×n 对齐字符串数组) | 变长/可增长;字符串数组等变长集合用此形式 | +| `{v0, v1, …}` | stringkeymap | 每元素落 `base·[i]` 坐标段独立子 key,容器值 langtype=map langtype(如 `[]char/utf8·int64`),storetype=index,主槽 body 空,成员名索引落 `base·` memindex | 变长/可增长;字符串数组等变长集合用此形式 | - compact 字面量降级为 `array(…)` 构造。变长字符串元素进 compact `[…]` 在 layout 语法检查期报错 (`compact array [...] cannot hold variable-length string element`)。 diff --git "a/stdlib/kvlang/spec/03-\347\261\273\345\236\213\347\263\273\347\273\237/11-stringkeymap\345\275\242\346\200\201.kv" "b/stdlib/kvlang/spec/03-\347\261\273\345\236\213\347\263\273\347\273\237/11-stringkeymap\345\275\242\346\200\201.kv" index 1ee937ed..5d702b21 100644 --- "a/stdlib/kvlang/spec/03-\347\261\273\345\236\213\347\263\273\347\273\237/11-stringkeymap\345\275\242\346\200\201.kv" +++ "b/stdlib/kvlang/spec/03-\347\261\273\345\236\213\347\263\273\347\273\237/11-stringkeymap\345\275\242\346\200\201.kv" @@ -4,7 +4,7 @@ lib kvlang/spec/类型系统/stringkeymap形态 { stringkeymap 数组的**容器值**是一个 storetype=index 的 XValue(langtype 为 map langtype,如 `[]char/utf8·int64`;body 空,成员名索引落 `base·` memindex,dims=[len,cap,M]),**每个元素**是独立 -子 key `base·i`: +子 key `base·[i]`(坐标段,见 [[数组两种物理形态]]): ```kv nums:[int64]·int64 = {10, 20, 30, 40} // 每元素落 nums·[0] … nums·[3] diff --git "a/stdlib/kvlang/spec/03-\347\261\273\345\236\213\347\263\273\347\273\237/16-ptr.kv" "b/stdlib/kvlang/spec/03-\347\261\273\345\236\213\347\263\273\347\273\237/16-ptr.kv" index 0cb7bb63..f61e6bb5 100644 --- "a/stdlib/kvlang/spec/03-\347\261\273\345\236\213\347\263\273\347\273\237/16-ptr.kv" +++ "b/stdlib/kvlang/spec/03-\347\261\273\345\236\213\347\263\273\347\273\237/16-ptr.kv" @@ -48,6 +48,7 @@ kv·abs(t, "2")`),均产 ref=1 Ptr、body 为目标 key 路径。 指向标量)时用显式 `*p`。二者不冲突:`*p` 取整值、`p·field` 取成员。 嵌套指针(`**T`)不在本模型内:wire 层 langtype 串不含 `*`、ref 仅单字节,无法表达层数。链表/树/取址 -皆一层指针,已覆盖;C 里 `**` 的「out 参数传地址」由 kvlang 写参(`-> (r:T)`)取代,无需 `**`。 +皆一层指针,已覆盖;C 里 `**` 的「out 参数传地址」由 kvlang 写参取代——要直写调用方对象就写 +`-> (r:*T)`(地址写参),`-> (r:T)` 是值写参(copy-in / copy-out),无需 `**`。 "#### -> /lib/kvlang/spec/类型系统/ptr } diff --git "a/stdlib/kvlang/spec/03-\347\261\273\345\236\213\347\263\273\347\273\237/17-struct.kv" "b/stdlib/kvlang/spec/03-\347\261\273\345\236\213\347\263\273\347\273\237/17-struct.kv" index fe9e8f10..b45f7606 100644 --- "a/stdlib/kvlang/spec/03-\347\261\273\345\236\213\347\263\273\347\273\237/17-struct.kv" +++ "b/stdlib/kvlang/spec/03-\347\261\273\345\236\213\347\263\273\347\273\237/17-struct.kv" @@ -25,5 +25,8 @@ q = Point{} // 全取默认:0.0, 0.0 在签名中,结构类型以原型路径 `/lib/`(**structref** 类型表达式 atom)标注(见 [[langtype签名类 型表达式]])。结构值可存进 map(int 键、struct 值)、以绝对路径指针连成链表/树/图(见 `tutorial/12-struct/`)。 + +struct 原型**不是**平行于 kvspace 的类型注册表——它就是 KV 树里的一个索引节点(`/lib/`,字段类型 +与默认值都是 KV 数据),故不与「数据结构全在 KV 树」的原则冲突(见 [[程序即数据结构]])。 "#### -> /lib/kvlang/spec/类型系统/struct } diff --git "a/stdlib/kvlang/spec/03-\347\261\273\345\236\213\347\263\273\347\273\237/18-\346\200\273\344\275\223\346\226\271\346\241\210.kv" "b/stdlib/kvlang/spec/03-\347\261\273\345\236\213\347\263\273\347\273\237/18-\346\200\273\344\275\223\346\226\271\346\241\210.kv" index 4f2db490..a2369c96 100644 --- "a/stdlib/kvlang/spec/03-\347\261\273\345\236\213\347\263\273\347\273\237/18-\346\200\273\344\275\223\346\226\271\346\241\210.kv" +++ "b/stdlib/kvlang/spec/03-\347\261\273\345\236\213\347\263\273\347\273\237/18-\346\200\273\344\275\223\346\226\271\346\241\210.kv" @@ -2,8 +2,8 @@ lib kvlang/spec/类型系统/总体方案 { r####"# 类型系统总体方案:xvalue head 三正交维 -> **本卷为新方案,待敲定。** 敲定后据此重构 [[种类与定宽类型]]、[[langtype签名类型表达式]]、[[数组形 - 态]]、[[map容器]]、[[struct]]。 +> **本卷即现行方案**(原「待敲定」状态已解除):head 三正交维 `ref` × `storetype` × `langtype` 已落 +> 地,本卷各章与其它各卷均据此书写。 每个 XValue 落入 kvspace 时,其类别由 head 三个**正交**字段表达,彻底取代旧的单一 `kind` 分类与 langtype 首字符 `*`/`@` 前缀。 diff --git "a/stdlib/kvlang/spec/03-\347\261\273\345\236\213\347\263\273\347\273\237/20-ref\345\255\230\345\202\250\344\275\215\347\275\256.kv" "b/stdlib/kvlang/spec/03-\347\261\273\345\236\213\347\263\273\347\273\237/20-ref\345\255\230\345\202\250\344\275\215\347\275\256.kv" index 74cad2ce..d5cb3cee 100644 --- "a/stdlib/kvlang/spec/03-\347\261\273\345\236\213\347\263\273\347\273\237/20-ref\345\255\230\345\202\250\344\275\215\347\275\256.kv" +++ "b/stdlib/kvlang/spec/03-\347\261\273\345\236\213\347\263\273\347\273\237/20-ref\345\255\230\345\202\250\344\275\215\347\275\256.kv" @@ -18,9 +18,10 @@ lib kvlang/spec/类型系统/ref存储位置 { ## 扩展世界句柄(ref=2 的 body 语义) ref=2 时 body **不是**真实值字节,而是**逻辑定位串**(如 `/networld//proc//stdout`); -langtype 仍为目标 langtype 串(不带 `@` 前缀),head 只存元描述。读取该 key 时 runtime 按 body 前缀 -**路由**到对应兑现器还原真实字节——如 `/lib/networld/*` 的 proc 兑现器把逻辑路径映射到 -`/tmp/kvlangruntime-rs//` 物理文件读回。真实 xvalue 落在扩展世界(fs 文件、gpu +langtype 仍为目标 langtype 串(不带 `@` 前缀),head 只存元描述。**`@` 的兑现交给支持它的 rwir**:如 +runtime-rs 的 `networld/proc` rwir 把逻辑路径 `/networld//proc//` 映射到 +`/tmp/kvlangruntime-rs//` 物理文件读回,`networld/fs` 一族 rwir 也直接以 `@` 开头的扩展 key +为输入;核心 runtime-c 不解引用 `@`。真实 xvalue 落在扩展世界(fs 文件、gpu tensordata),非 kvspace 元存;扩展算子的输出即以此形式写回其写槽。锚例: `tutorial/14-networld/05-capture.kv`。 "#### -> /lib/kvlang/spec/类型系统/ref存储位置 diff --git "a/stdlib/kvlang/spec/03-\347\261\273\345\236\213\347\263\273\347\273\237/21-storetype\347\211\251\347\220\206\345\270\203\345\261\200.kv" "b/stdlib/kvlang/spec/03-\347\261\273\345\236\213\347\263\273\347\273\237/21-storetype\347\211\251\347\220\206\345\270\203\345\261\200.kv" index cee20aba..0ac0e04a 100644 --- "a/stdlib/kvlang/spec/03-\347\261\273\345\236\213\347\263\273\347\273\237/21-storetype\347\211\251\347\220\206\345\270\203\345\261\200.kv" +++ "b/stdlib/kvlang/spec/03-\347\261\273\345\236\213\347\263\273\347\273\237/21-storetype\347\211\251\347\220\206\345\270\203\345\261\200.kv" @@ -7,9 +7,9 @@ lib kvlang/spec/类型系统/storetype物理布局 { | storetype | 追加物理字段 | body(ref=0) | 承载的 langtype | |-----------|-------------|--------------|----------------| | `NONE` | 无 | 空 | None | -| `ATOM` | 无 | 定宽 raw | 标量:bool、int/uint/float、单 char、time、duration | -| `ARRAYND` | `ndim` u8 + `dims[ndim]` u32 LE | 稠密等宽元素数组 | 张量、`[]char/*` 字符串、rwir 指令行文本 | -| `index` | 成员名 **m×n 对齐字符串数组**,`dims=[len,cap,M]`(len=成员数、M=对齐宽度 align8、cap 保留容量) | 见下(目录节点主槽 body 记计数头或空) | stringkeymap、struct(值容器);lib、rwfunc、def 族(目录/定义节点) | +| `ATOM` | 无 | 单段不可切分 raw:定宽标量,或变长文本(`rwir` 槽 = 计数头 + 文本;`def langtype` 类型串) | 标量:bool、int/uint/float、time、duration;代码叶子 `rwir`、签名定义槽 `def langtype` | +| `ARRAYND` | `ndim` u8 + `dims[ndim]` u32 LE | 稠密等宽元素数组 | 张量、`[]char/*` 字符串(`.src` 源码副本亦此形) | +| `index` | 成员名 **m×n 对齐字符串数组**,`dims=[len,cap,M]`(len=成员数、M=对齐宽度 align8、cap 保留容量) | 空(rwfunc 的计数头在 `[0,0]`、值容器在 `{key}·`) | stringkeymap、struct(值容器);lib、rwfunc、def 族(目录/定义节点) | | `extindex` | 同 index,`cap` 可增长(栈帧/运行栈扩容) | 同上 | rwfunc(vthread 运行栈等可扩展目录) | 数值 `dims` 供 codec O(1) 切字节,与 langtype 串内的 `[dims]` 语法一致(由 codec 保证同步)。 @@ -45,9 +45,9 @@ storetype=index/extindex 只表「这是有成员的索引节点」,成员的* | langtype | 有 kvlang 实现体? | 位置 | 谁实现 | 形态 | |----------|------------------|------|--------|------| -| `rwir` | 无 | `/vthread//` 指令行 | runtime 直接兑现(经 def rwir 路由,myrwircaps) | ARRAYND 指令行叶子 | +| `rwir` | 无 | `/vthread//` 指令行 | runtime 直接兑现(经 def rwir 路由,myrwircaps) | ATOM 指令叶子(body = 计数头 + 指令名/引用文本) | | `def rwir` | 无(仅签名,无指令行) | **仅 `/lib/`** | runtime 直接兑现 | index **定义节点**(有签名行 `[0,x]`,无实现指令行) | -| `rwfunc` | **有**(一串 rwir 指令行) | `/lib/·/` | kvlang 指令序列自身 | index/extindex **目录**(签名行 `[0,x]` + 实现指令行 `[s0>0,·]`) | +| `rwfunc` | **有**(一串 rwir 指令行) | `/lib/·/` | kvlang 指令序列自身 | index/extindex **目录**(参数定义键 `.[0,±j]` + 实现指令行 `[s0>0,·]`) | **def rwir 是路由头**(原 `defrwir`,现规范书写为带空格的 **`def rwir`**,见下「def 族」):它只存在 于 `/lib/`,是每个 rwir 指令的统一声明入口。`/vthread/` 下执行的每条 rwir 都**引用** `/lib/` diff --git "a/stdlib/kvlang/spec/03-\347\261\273\345\236\213\347\263\273\347\273\237/22-storetype-def\346\227\217\344\270\216\347\255\276\345\220\215\350\241\214.kv" "b/stdlib/kvlang/spec/03-\347\261\273\345\236\213\347\263\273\347\273\237/22-storetype-def\346\227\217\344\270\216\347\255\276\345\220\215\350\241\214.kv" index 369e65a4..b7195e88 100644 --- "a/stdlib/kvlang/spec/03-\347\261\273\345\236\213\347\263\273\347\273\237/22-storetype-def\346\227\217\344\270\216\347\255\276\345\220\215\350\241\214.kv" +++ "b/stdlib/kvlang/spec/03-\347\261\273\345\236\213\347\263\273\347\273\237/22-storetype-def\346\227\217\344\270\216\347\255\276\345\220\215\350\241\214.kv" @@ -10,27 +10,31 @@ lib kvlang/spec/类型系统/storetype_def族与签名行 { 名 参数键 `{name}` 的 Ptr(其 langtype 即该参类型)承载(按名解析)。 -rwfunc / def rwir 的**签名(各参数类型)不写进 langtype 串**,也不塞进主槽 body。主槽只记计数头,参 -数 -类型按种类分路承载: +rwfunc / def rwir 的**签名(各参数类型)不写进 langtype 串**,也不塞进计数头节点的 body。计数头只记 +计数,参数类型按种类分路承载: -1. **主槽计数头**(两者共有):目录节点主槽 `{fn}`(如 `/lib/pkg·funca`)的 body 只记 - `[nr:u16 LE][nw:u16 LE][dynamic:u8]`——读参个数 `nr`、写参个数 `nw`、是否变参 `dynamic`(末位读参 - `...`)。**不含任何参数 langtype 串**。 +1. **计数头**(两者共有):`rwfunc` 落签名行锚点 `/lib/pkg·funca/[0,0]`、`def rwir` 落 `/lib/` 节点 + 自身,其 body 只记 `[nr:u16 LE][nw:u16 LE][dynamic:u8]`——读参个数 `nr`、写参个数 `nw`、是否变参 + `dynamic`(末位读参 `...`)。**不含任何参数 langtype 串**。rwfunc 的函数目录节点自身是普通 index、 + 无值。 2. **def rwir——位置化 `[0,x]` 签名槽**:每个参数类型落该目录签名行坐标 `[0,x]`——`x<0` 读参、`x>0` 写参、`[0,0]` 为锚点(见 [[指令布局格式]] 二元坐标 `[s0,s1]`,`s0=0` 即签名行)。每个 `[0,x]` 是 - **`def langtype`** xvalue,body 存该参数完整 langtype 串(一参一槽),**纯净、不含变参 `...`**—— + **`def langtype`** xvalue,body 存该参数的 **def langtype**(匹配类型)串(一参一槽),**纯净、不含变参 + `...`**—— 变 - 参是 arity,只落主槽 `dynamic` 字节。跨 runtime 队列按位置收参,故须有序签名。 + 参是 arity,只落计数头的 `dynamic` 字节。跨 runtime 队列按位置收参,故须有序签名。 3. **rwfunc——参数定义键 `funcDir.[0,±j]` 承载**:func 目录根**不**落 `/` 坐标槽;每个参数随点后缀 键 `funcDir.[0,-j]`(读参)/ `funcDir.[0,+j]`(写参)承载——langtype `def langtype`,body = 参数 - 名 + NUL + 该参数完整类型串。点后缀与坐标斜杠键 `/[0,±j]` 不同名,故运行期向帧根 + 名 + NUL + 该参数的 **def langtype**(匹配类型)串。点后缀与坐标斜杠键 `/[0,±j]` 不同名,故运行期向帧根 `frameRoot/[0,±j]` 写实参地址 Ptr 时不会撞上只读静态节点;参数顺序由键中的 `±j` 显式记录(命名 键不保序),rwfunc 按位置取参、只区分读/写。 -于是 rwfunc/def rwir 主槽 langtype 都是裸种类名 `rwfunc` / `def rwir` 本身,**非「签名 langtype -串」**。def rwir 的签名散在 `[0,x]` 槽、rwfunc 的散在 `.[0,±j]` 键;实现指令行(若有)在 -`[s0>0,·]`。 +于是计数头节点的 langtype 都是裸种类名 `rwfunc`(rwfunc 的 `/lib/pkg·funca/[0,0]`)/ `def rwir` +(def rwir 的 `/lib/` 节点自身)本身,**非「签名 langtype 串」**。def rwir 的签名散在 `[0,x]` 槽、 +rwfunc 的散在 `.[0,±j]` 键;实现指令行(若有)在 `[s0>0,·]`。 + +**符号即读写属性(永久规定)**:参数定义键 `.[op,param]` 中 `param<0` 是**只读参数**(读参)、 +`param>0` 是**要写的参**(写参)——函数体内读参一律不得作写槽(含成员/下标/别名路径,见 [[函数]])。 ### def 族:定义节点的 langtype(带空格书写) diff --git "a/stdlib/kvlang/spec/03-\347\261\273\345\236\213\347\263\273\347\273\237/23-langtype\350\257\255\344\271\211\347\261\273\345\236\213.kv" "b/stdlib/kvlang/spec/03-\347\261\273\345\236\213\347\263\273\347\273\237/23-langtype\350\257\255\344\271\211\347\261\273\345\236\213.kv" index 1220cb42..a6fd162d 100644 --- "a/stdlib/kvlang/spec/03-\347\261\273\345\236\213\347\263\273\347\273\237/23-langtype\350\257\255\344\271\211\347\261\273\345\236\213.kv" +++ "b/stdlib/kvlang/spec/03-\347\261\273\345\236\213\347\263\273\347\273\237/23-langtype\350\257\255\344\271\211\347\261\273\345\236\213.kv" @@ -2,7 +2,7 @@ lib kvlang/spec/类型系统/langtype语义类型 { r####"# langtype(语义类型维,语言视角) -本章界定 **value langtype**——一个具体值 head 的 langtype(两型 def/value 与 kindexpr 简写见 +本章界定 **langtype**——一个具体值 head 的**真实类型**(它与定义处匹配类型 `def langtype` 的区别见 [[langtype签名类型表达式]])。langtype 是完整的类型表达式串,逐字节即类型标注文法,天然含 base 种 类、`[dims]`、map 键值、struct 原型路径。各 langtype 的串形态与其落定的 storetype: @@ -12,13 +12,13 @@ lib kvlang/spec/类型系统/langtype语义类型 { | `[]char/utf8` | ARRAYND(elem 1B) | **utf8 变宽 → 物理即 [n]uint8**;禁码点索引是 langtype 层规则,物理按字节切 | | `[]char/utf32` `[]char/ascii` | ARRAYND | 定宽,物理可 O(1) 码点索引 | | `[3,4]float32` | ARRAYND | 张量 | -| `rwir`(指令行,`/vthread/`) | ARRAYND | 指令行叶子,**无实现体,由 runtime 经 def rwir 路由直接兑现(myrwircaps)** | +| `rwir`(指令行,`/vthread/`) | ATOM | 指令叶子(body = 计数头 + 指令名/引用文本),**无实现体,由 runtime 经 def rwir 路由直接兑现(myrwircaps)** | | `def rwir`(路由头,仅 `/lib/`) | index | 定义节点:签名行 `[0,x]`,无实现指令行 | | `[]char/utf8·int64`(map) | index | **stringkeymap**,键值经 `·` mapexpr;成员在 `{key}·` | | `/lib/Point`(struct 原型路径) | index | 结构实例,字段固定;成员在 `{key}·` | | `def struct`(原型定义节点) | index | struct 原型自身;字段类型定义在其子槽 | -| `rwfunc` | index / extindex | 函数即 `/` 目录:签名行 `[0,x]` + 实现指令行;主槽 body 只记 nr/nw/dynamic | -| `def langtype`(签名行 `[0,x]` 槽) | ATOM | 单个参数类型定义,body=该参数 langtype 串 | +| `rwfunc` | index / extindex | 函数即 `/` 目录:签名行锚点 `[0,0]`(langtype `rwfunc`,body 只记 nr/nw/dynamic)+ 参数定义键 `.[0,±j]` + 实现指令行;目录节点自身为 `index`、无值 | +| `def langtype`(签名行 `[0,x]` 槽) | ATOM | 单个参数的**匹配类型**定义,body=该参数的 def langtype 串 | | `lib`(包目录) | index | `/lib/` 及各 pkg 目录;成员为 `/` 子路径 | **def 族的来源**(`def` 不是 kvlang 关键字、不在 kv 源码书写):`def struct`(源码 `struct Name{}`, @@ -26,8 +26,8 @@ layout 落原型定义节点)、`def langtype`(源码参数标注 `x:int64` **layout** 产生;`def rwir`(`/lib/` 路由头)**由各 runtime 注册**——kv 源码不声明 rwir,layout 也不产生 def rwir(见 [[rwfunc布局与def_rwir]])。 -`object`/`scope` **彻底不存在**——无此种类名、无此关键字;异构命名容器一律是 `struct`(见 [[容 -器]])。容器**语义类型**只剩 `stringkeymap`、`struct`(口语称「map」指的即 stringkeymap,规范一律书 +`object`/`scope` **彻底不存在**——无此种类名、无此关键字;异构命名容器一律是 `struct`(见 +[[struct]])。容器**语义类型**只剩 `stringkeymap`、`struct`(口语称「map」指的即 stringkeymap,规范一律书 写种类名 `stringkeymap`)。 **一对多正是拆分的价值**:同为 rwfunc,静态函数定义落 `index`、vthread 运行栈落 `extindex`;语言层看 diff --git "a/stdlib/kvlang/spec/03-\347\261\273\345\236\213\347\263\273\347\273\237/24-wire\345\270\203\345\261\200\347\244\272\344\276\213.kv" "b/stdlib/kvlang/spec/03-\347\261\273\345\236\213\347\263\273\347\273\237/24-wire\345\270\203\345\261\200\347\244\272\344\276\213.kv" index ba0df317..c75f24aa 100644 --- "a/stdlib/kvlang/spec/03-\347\261\273\345\236\213\347\263\273\347\273\237/24-wire\345\270\203\345\261\200\347\244\272\344\276\213.kv" +++ "b/stdlib/kvlang/spec/03-\347\261\273\345\236\213\347\263\273\347\273\237/24-wire\345\270\203\345\261\200\347\244\272\344\276\213.kv" @@ -14,9 +14,10 @@ map : U(store=index)[count/cap…][lang="[]char/utf8·int64"] | 主 struct 实例 : U(store=index)[count/cap…][lang="/lib/Point"] | 主槽空;成员在 {key}· def struct : U(store=index)[count/cap…][lang="def struct"] | Point 原型;字段定义在子槽 /lib/ : U(store=index)[count/cap…][lang="lib"] | 成员为 /lib/ 子路径 -/lib/pkg·funca : U(store=index)[count/cap…][lang="rwfunc"] | body=[nr][nw][dyn];签名在 [0,x],实现在 [s0>0,·] +/lib/pkg·funca : 目录节点 U(store=index)[lang="index"](无值);其 [0,0] : U(store=index)[lang="rwfunc"] | body=[nr][nw][dyn];签名在 .[0,±j],实现在 [s0>0,·] /lib/ : U(store=index)[count/cap…][lang="def rwir"] | 路由头;body=[nr][nw][dyn];签名在 [0,x],无实现行 签名行 [0,x]: U(store=ATOM)[lang="def langtype"] | body=该参数 langtype 串 +rwir 指令行 : U(store=ATOM)[lang="rwir"] | body=[nr][nw][dyn](指令槽恒 0)+ 指令名/引用文本 /vthread/1/ : U(store=extindex)[ext 元数据][lang="rwfunc"] | 运行栈,/vthread/1/<坐标> 子成员 ptr→int64 : U(ref=1,store=ATOM)[lang="int64"] | body="/x/y" ptr→rwfunc : U(ref=1,store=index)[lang="rwfunc"] | body="/lib/pkg·funca"(调用链) diff --git "a/stdlib/kvlang/spec/03-\347\261\273\345\236\213\347\263\273\347\273\237/25-\345\267\262\346\225\262\345\256\232.kv" "b/stdlib/kvlang/spec/03-\347\261\273\345\236\213\347\263\273\347\273\237/25-\345\267\262\346\225\262\345\256\232.kv" index 388da1e1..54744f84 100644 --- "a/stdlib/kvlang/spec/03-\347\261\273\345\236\213\347\263\273\347\273\237/25-\345\267\262\346\225\262\345\256\232.kv" +++ "b/stdlib/kvlang/spec/03-\347\261\273\345\236\213\347\263\273\347\273\237/25-\345\267\262\346\225\262\345\256\232.kv" @@ -10,19 +10,37 @@ lib kvlang/spec/类型系统/已敲定 { - 容器语义类型只剩 `stringkeymap`/`struct`(口语「map」= stringkeymap;`object`/`scope` **彻底删除 **,无此种类/关键字);物理落 index。 - 字符串:ascii/utf32 → ARRAYND;utf8 → ARRAYND(elem 1B)。 -- time/duration → ATOM;rwir 指令行 → ARRAYND 叶子(无实现体)。 +- time/duration → ATOM;rwir 指令行 → ATOM(body = 计数头 + 指令名文本,无实现体)。 - **rwir vs rwfunc 的本质区别**:rwir 无实现指令行、由 runtime 直接兑现(myrwircaps);rwfunc 有 kvlang 实现指令行(`/` 目录下的 `[s0>0,·]`)→ 目录。 - **def rwir 是路由头**(原 defrwir):仅存于 `/lib/`,是 rwir 统一调度入口;`/vthread/` 的每条 rwir 引用 `/lib/` 的 def rwir。**无「扩展 rwir」之说**,只有各 runtime 的 myrwircaps。 -- **签名不入 langtype 串**:rwfunc/def rwir 主槽 langtype 即裸名 `rwfunc`/`def rwir`;主槽 body 只记 - `[nr][nw][dynamic]`;各参数真实类型落在签名行 `[0,x]` 槽(`x<0` 读参、`x>0` 写参、`[0,0]` 锚点), - 每槽为 `def langtype` xvalue(body=该参数 langtype 串)。 +- **签名不入 langtype 串**:计数头节点的 langtype 为裸名 `rwfunc`(`/lib/·/[0,0]`)/ + `def rwir`(`/lib/` 节点自身);其 body 只记 `[nr][nw][dynamic]`;参数真实类型按符号分两路承 + 载——`def rwir` 落位置化签名行 `[0,x]` 槽(`x<0` 读参、`x>0` 写参、`[0,0]` 锚点),`rwfunc` 落参数定 + 义键 `.[0,±j]`;两者都是 `def langtype` xvalue。 +- **ATOM = 单段不可切分 raw**:定宽标量(bool/int/uint/float/time/duration)与**变长文本**(`rwir` 槽 = + 计数头 + 文本、`def langtype` 类型串)同落 ATOM;ARRAYND 只承载带 `ndim`/`dims` 的稠密数组(张量、 + `[]char/*`)。 +- **`rwir` 槽 body 的唯一格式**:`[nr:u16 LE][nw:u16 LE][dynamic:u8]`(指令槽恒 `0,0,0`,5 字节)+ + 槽文本(opcode 名或相对指针)。构造侧 `kvkind::rwir_slot_body`、读取侧 `kvlangXvalueSlotName` 均按此 + 约定(`body + 5`);内联字面量不是 `rwir`,按自身 kind 编码、无计数头。 +- **参数传递由签名 ref 前缀定**(见 [[函数]]):`T` 值传(帧槽存副本)、`*T` 址传(值在 kvspace,体内解 + 引用一层)、`@T` 扩展存储(值在 kvspace 之外,runtime-c 不可直达,由**支持 `@` 的 rwir** 按定位串兑现 + ——如 runtime-rs 的 fs/networld 一族);值容器(map langtype / struct 原型路径)无值本体可拷,**必 + 须**带 `*`/`@`。**读参一律只读**:参数定义键 `.[0,param]` 中 `param<0` 是只读参数、`param>0` 是要写 + 的参——与值传/址传无关(见 [[函数]])。 +- **opcode 槽的 `rwir|rwfunc` 是派发标记**,不是值类型(见 [[指令槽编码]])。 +- **`langtype` 与 `def langtype` 的区别**:`langtype` 是值的**真实类型**(具体、单一种类 + 确定 + `[dims]`);`def langtype` 是定义函数时参数/返回值的**匹配类型**(可含并集/轴量词/`any`),**一个 + def langtype 可匹配多种 langtype**——调用时按它逐值判定(见 [[langtype签名类型表达式]]、[[匹配语义与 + 变参]])。承载 def langtype 的节点 kind 就叫 `def langtype`。 - **def 族带空格书写**:`def rwir`、`def struct`、`def langtype`——`def` 与 base 间强制空格,连写形式 废除。 - **rwfunc/lib 是目录节点**:成员即 `/` 子路径;rwfunc 静态定义 → index、vthread 运行栈 → extindex。 - **index/extindex 物理载体 = m×n 对齐字符串数组**(`dims=[len,cap,M]`,M align8、cap 扩容),沿用今 - 日敲定方案,存成员/子项名。 + 日敲定方案,存成员/子项名;载体**语义是可枚举成员**(`kvspaceListLen`/`ListAt`),shm 用矩阵、fs 用 + `{key}·/` 子目录,载体差异不影响 ABI 语义。 - **`·` 双义正交**:① memindex 标记 `{key}·` 仅 stringkeymap/struct 用;② `/lib/{pkg}·{func}` 里的 `·` 是包·函数命名分隔符(路径名一部分),与 memindex 无关,rwfunc 目录成员仍走 `/`。 - 索引型容器(stringkeymap/struct)主槽 `{key}` body 恒空。 diff --git "a/stdlib/kvlang/spec/04-layout\350\257\255\344\271\211/02-\346\214\207\344\273\244\346\247\275\347\274\226\347\240\201.kv" "b/stdlib/kvlang/spec/04-layout\350\257\255\344\271\211/02-\346\214\207\344\273\244\346\247\275\347\274\226\347\240\201.kv" index f5fe1ea1..548d2d63 100644 --- "a/stdlib/kvlang/spec/04-layout\350\257\255\344\271\211/02-\346\214\207\344\273\244\346\247\275\347\274\226\347\240\201.kv" +++ "b/stdlib/kvlang/spec/04-layout\350\257\255\344\271\211/02-\346\214\207\344\273\244\346\247\275\347\274\226\347\240\201.kv" @@ -19,9 +19,9 @@ opcode 位恒为操作码,故拷贝(opcode=`=`)与零参函数调用(`gr opcode 槽 `[s0,0]` 的 langtype 由 layout 按 opcode 类别决定: - 控制流与拷贝原语(`return` / `goto` / `br` / `call` / `=`)——langtype `rwir`。 -- 其余(运算符、函数/rwir 调用目标)——langtype `rwir|rwfunc`。layout **不**静态判定该目标是否在本 - runtime 的 myrwircaps 内(rwir)或为 rwfunc;判定推迟到 runtime 查 `/lib/` 分派(见 [[lib - 与rwir数据]])。 +- 其余(运算符、函数/rwir 调用目标)——langtype `rwir|rwfunc`。这是**派发标记**(非值类型):layout + **不**静态判定该目标是否在本 runtime 的 myrwircaps 内(rwir)或为 rwfunc;判定推迟到 runtime 查 + `/lib/` 分派(见 [[lib与rwir数据]])。 ## 读写槽的槽值编码 diff --git "a/stdlib/kvlang/spec/04-layout\350\257\255\344\271\211/03-\345\207\275\346\225\260.kv" "b/stdlib/kvlang/spec/04-layout\350\257\255\344\271\211/03-\345\207\275\346\225\260.kv" index 8a7aa076..8769dbdc 100644 --- "a/stdlib/kvlang/spec/04-layout\350\257\255\344\271\211/03-\345\207\275\346\225\260.kv" +++ "b/stdlib/kvlang/spec/04-layout\350\257\255\344\271\211/03-\345\207\275\346\225\260.kv" @@ -24,7 +24,7 @@ kvlang 源码只有一种命名单元:**rwfunc**(有指令体的用户函数 调用时**写参 arity 必须全部匹配**(对齐 Go/Rust):`f() -> s` 对多写参函数是错误;不需要的写参**必须 **用 `_` 显式丢弃。 -## 参数类型必须标注,且**不得**写指针前缀 +## 参数类型除了值类型,还可以标注 `*` 传址、`@` 扩展存储 每个读参与写参**必须**声明类型(`name:type_expr`,type_expr 见 [[langtype签名类型表达式]])。 缺类型标注是错误: @@ -34,81 +34,104 @@ error: func f: param "x" has no type annotation — every parameter must declare error: func f: return value "r" has no type annotation ``` -参数类型**禁止**写 `*` 前缀(如 `p:*Point` 是错误)。kvlang 只有**地址传递**,而这件事由 layout -自动完成:函数体里每个形参引用都被 lower 成 `*[0,±k]`(参数轴槽存的是实参地址,显式解引用才取到 -值,见 [[指令架构]])。故 `p:*Point` 与 `p:Point` 完全等价,签名里那个 `*` 是纯噪声,只会让人误以为 -「值传递 / 地址传递」在签名层可选: +参数类型除了值类型(不写前缀,实参值拷进帧槽),还可以在类型最前标注 `*`/`@`——它们是 head 的 `ref` +前缀(见 [[ref存储位置]]),两个**正交维**:`*` 说「多一跳间接」,`@` 说「值不在 kvspace」: -``` -error: func f: param "p": pointer type "*/lib/Point" is not allowed — parameter references are - already lowered to `*[0,±k]` (the axis slot holds the argument address), so write "/lib/Point" -``` +| 签名写法 | 值在哪 | 帧槽 `[0,±k]` 存什么 | 体内形参引用 | +|---------|--------|--------------------|-------------| +| `x:T` | 本帧 | 调用方该位置的值**复制**进槽 | `[0,±k]` **只读**(`param<0` 只读,见下) | +| `p:*T` | kvspace 内某个 key | 该 key 的路径(ref=1 Ptr) | `*[0,±k]` 解引用一次取实参值(**只读**) | +| `h:@T` | **kvspace 之外**(fs 文件、GPU 显存、外部进程输出…) | 扩展世界定位串(ref=2) | runtime-c **不可**直接读写;由**支持 `@` 的 rwir**(如 runtime-rs 的 fs/networld 一族)按定位串兑现 | + +`*T` 与 `@T` 都"不是值本体",但性质不同:`*` 是**间接**——指针的值(那段 key 路径)本身就存在 kvspace +的 body 里,故 layout 与 runtime-c 都能直接寻址、解引用;`@` 是**位置陈述**——值本体不在 kvspace, +runtime-c 寻不到,**由支持 `@` 的 rwir 自己兑现**——这些 rwir 在其实现里按 head 的 ref=2 定位串读写扩展 +世界的真实字节(如 runtime-rs 的 networld/fs 一族 rwir 直接以 `@` 开头的扩展 key 为输入)。核心 +runtime-c 不解引用 `@`,也不设通用 extresolver。 + +值容器(map langtype、struct 原型路径)**没有可复制的值本体**,**必须**带 `*`(值在 kvspace)或 `@` +(值在扩展世界)——`p:/lib/Point` 是错误,须写 `p:*/lib/Point`;标量、compact 数组、`[]char/*` 字符串 +写 `T` 即按值传递。 -由此,`p:Point` 的 `p·field = v` 改的是**调用方那个对象**(参数槽本身没动);`*T` 仍用于 struct -字段与局部标注——那里确实要区分「指向节点的引用」与节点本身。`@` 前缀(ref=@ext)不受此限。 +参数声明的类型串是 **def langtype**(定义处的匹配类型,见 [[langtype签名类型表达式]]):它可含并集与 +`any`,故**同一参数可接受多种 `langtype` 的实参**(如 `a:int8|int16` 同时接受 int8 与 int16 值)。 + +由此:读参(`param<0`,不论值传/址传)**只读**——`p:*Point` 的 `p·field = v`、值参 `x:int64` 的 +`x = x + 1` 都是写槽命中读参,layout 报错。要改值就先拷到新局部变量(`x -> local`,此后写 `local`);要 +改调用方对象就把该参数放到写参侧(`-> (p:*/lib/Point)`)。写参(`param>0`)可读可写:`-> (p:*/lib/Point)` +直写调用方对象,`-> (acc:int64)` 值写参按 [[系统变量]] 的 `‥wdst` 表 copy-in / copy-out。 ## 参数变参(arity,非类型) 末读参**可**在参数上尾缀 `...` 声明变参(吸收 0..N 个同型实参,如 `A:int64|float64...`)。`...` 是** 签名层 arity 构造,不是 type_expr 的一部分**(轴量词见 [[langtype签名类型表达式]]):layout 解析时把 -它从参数上**剥离**,给该函数主槽置 `dynamic=1`(见 [[指令布局格式]]),而参数的**纯净** langtype(不含 -`...`)由承载点存放——def rwir 落 `[0,x]` 子槽、rwfunc 随 `{name}` Ptr 的 langtype(此键为签名元数 -据,不参与运行时形参解析,见 [[调用extindex]])。故 `LangtypeValid`/`LangtypeMatch` 永不见 `...`。 +它从参数上**剥离**,给该函数的签名行锚点 `[0,0]` 置 `dynamic=1`(见 [[指令布局格式]]),而参数的**纯净** langtype(不含 +`...`)由承载点存放——def rwir 落位置化签名槽 `[0,x]`、rwfunc 落参数定义键 `.[0,±j]`(两者都是 +`def langtype`,rwfunc 的 body = 参数名 + NUL + 类型串;此键为签名元数据,不参与运行时形参解析,见 +[[调用extindex]])。故 `LangtypeValid`/`LangtypeMatch` 永不见 `...`。 - 变参**必须**是最后一个读参;非末位读参带 `...`:装载期错误。 - 写参(返回值)**不得**变参:装载期错误。 -- 派发时,主槽 `dynamic=1` 则末读参对每个尾随实参按其纯净 langtype 逐个判定(见 [[匹配语义与变 +- 派发时,签名行锚点 `dynamic=1` 则末读参对每个尾随实参按其纯净 langtype 逐个判定(见 [[匹配语义与变 参]])。 -## 写参初值 None +## 写参初值 -写参在被调方帧内初值为 **None**(strict null)。函数体内**必须**先显式初始化写参再参与运算——对 None -做算术在 runtime 被拒。惯例以拷贝置零值起步(`0 -> acc`),此后写参在体内可读可写,退出时经箭头映射 -回调用方。 +值写参(`-> (acc:int64)`)的初值是**调用方该位置的当前值**——调用点把它 copy-in 进帧槽 `[0,+k]`,返回时 +按 `‥wdst` copy-out 回目标(累加器写法 `acc + x -> acc` 据此拿初值)。地址写参(`-> (p:*T)`)的帧槽存 +调用方目标地址,`*[0,+k]` 解引用即调用方当前值。调用方位置尚未赋值时初值即 None——对 None 做算术在 +runtime 被拒,故累加器写法前须保证目标已有值(如 `0 -> acc` 起步)。 -## 读参只读 +## 读参只读(`param<0` 一律只读) -读参是单向输入绑定。函数体内把读参裸名放入写槽(含 `for … in` 的迭代变量)会破坏数据流方向,layout -报错拒绝装载: +**永久规定**:参数定义键 `.[op,param]` 中 `param<0` 是**只读参数**(读参)、`param>0` 是**要写的参** +(写参,见 [[storetype_def族与签名行]])。函数体内读参的裸名**一律**不得作写槽(含 `for … in` 的迭代 +变量、成员/下标写、`kv·set(base, …)` 的 base),layout 报错拒绝装载: ``` error: func f: read param "A" cannot be used as write slot (read params are read-only) ``` -**只读覆盖到子成员,且别名不洗白**:`p·field = v`、`p[k] = v`、`kv·set(p, k, v)` 同样命中该检查 -——经 desugar 后 base 就是读参裸名。只读性还沿别名传播:`q = p` / `p -> q` 使 `q` 指到**同一个 -对象**,此后 `q·field = v` 写的仍是 `p` 的对象,layout 一并拒绝(否则一句话就能绕开本规则): +只读与**值传/址传无关**:值读参的槽是本帧副本、地址读参(声明带 `*`/`@`)的槽是调用方对象的地址,两者 +都只读——写值读参就是写一个只读的帧槽,写地址读参还会破坏数据流方向。要改值就先拷到新局部变量 +(`x -> local`,此后写 `local`);要就地改调用方对象就把该参数放到写参侧(`-> (p:*/lib/Point)`)。 + +**只读覆盖到子成员,且别名不洗白**:`p·field = v`、`p[k] = v`、`kv·set(p, k, v)` 同样命中该检查——经 +desugar 后 base 就是读参裸名;对地址读参,只读性还沿别名传播:`q = p` / `p -> q` 使 `q` 指到**同一个对 +象**,此后 `q·field = v` 写的仍是 `p` 的对象,layout 一并拒绝(否则一句话就能绕开本规则): ``` error: func f: read param "p" cannot be used as write slot (read params are read-only) error: func f: "q" aliases read param "p" (`q = p`); writing its members writes that object - — put it on the write side: `-> (p:/lib/Point)` + — put it on the write side: `-> (p:*/lib/Point)` ``` -(`q·next -> q` 这类**重绑别名本身**的写槽是裸名、不碰调用方对象,不受影响。) - -**签名诚实原则**:函数体内被写的参数**必须**声明在写参侧。要就地改调用方的对象,就把该参数写到 -`-> (p:Point)` 里——kvlang 只有地址传递,写参 `p` 拿到的就是调用方对象的地址: +**签名诚实原则**:要就地改调用方的对象,就把该参数写到写参侧、并按地址声明: ```kv -rwfunc shift(dx:int64) -> (p:*Point) { p·x + dx -> p·x } +rwfunc shift(dx:int64) -> (p:*/lib/Point) { p·x + dx -> p·x } rwfunc test() -> () { a:Point = {x=1 y=2} shift(10) -> a } ``` ``` -// 非法:acc 被写却在读参侧 -rwfunc sum(arr:[]int64, acc:int64) -> (r:int64) { acc + arr[0] -> acc } -// 合法:acc 在写参侧,体内可读可写 -rwfunc sum(arr:[]int64) -> (acc:int64) { acc + arr[0] -> acc } +// 非法:读参 p 是地址参(*),写它的成员就是写调用方对象 +rwfunc bump(p:*/lib/Point) -> () { p·x + 1 -> p·x } +// 非法:读参 x 按值传也只读(param<0)——要改先拷到新局部变量 +rwfunc inc(x:int64) -> (r:int64) { x = x + 1 x -> r } +// 合法:同一个对象放到写参侧(地址写参直写调用方) +rwfunc bump() -> (p:*/lib/Point) { p·x + 1 -> p·x } +// 合法:先拷到局部变量再改 +rwfunc inc(x:int64) -> (r:int64) { x -> local local = local + 1 local -> r } ``` -判定规则(实现):写槽含 `/`、`[`、`·` 者视为路径/下标/成员写,不计入本检查;但 `kv·set(base, …)` 的 -base 命中读参裸名同样拒绝(成员目录被改写)。 +(`q·next -> q` 这类**重绑别名本身**的写槽是裸名、不碰调用方对象,不受影响。)判定规则(实现):写槽 +含 `/`、`[`、`·` 者视为路径/下标/成员写,不计入本检查;但 `kv·set(base, …)` 的 base 命中读参裸名同样 +拒绝(成员目录被改写)。 ## 参数同名规则 -- **定义时**:读参与写参**不得**同名——`rwfunc f(A:int64) -> (A:int64)` 非法,报 - `param "A" appears in both read-params and write-params`。 +- **定义时**:读参列表内、写参列表内、以及读写列表之间均**不得**同名(变量名即指针,同名即同址)—— + `rwfunc f(A:int64) -> (A:int64)` 报 `param "A" appears in both read-params and write-params`。 - **调用时**:同一变量**可**同时出现在读槽与写槽——`inc(x) -> x` 合法,读写独立解析、互不冲突。 "#### -> /lib/kvlang/spec/layout语义/函数 } diff --git "a/stdlib/kvlang/spec/04-layout\350\257\255\344\271\211/04-\345\207\275\346\225\260\345\206\231\346\247\275\344\270\216\345\270\203\345\261\200.kv" "b/stdlib/kvlang/spec/04-layout\350\257\255\344\271\211/04-\345\207\275\346\225\260\345\206\231\346\247\275\344\270\216\345\270\203\345\261\200.kv" index 080b8002..45347d30 100644 --- "a/stdlib/kvlang/spec/04-layout\350\257\255\344\271\211/04-\345\207\275\346\225\260\345\206\231\346\247\275\344\270\216\345\270\203\345\261\200.kv" +++ "b/stdlib/kvlang/spec/04-layout\350\257\255\344\271\211/04-\345\207\275\346\225\260\345\206\231\346\247\275\344\270\216\345\270\203\345\261\200.kv" @@ -17,12 +17,12 @@ rwfunc 布进 `/lib/·/`: 1. `[0,0]`——签名行锚点,langtype `rwfunc`,body `[nr:u16 LE][nw:u16 LE][dynamic:u8]`(读参数/写参数/ 是否变参),仅此计数头。rwfunc **不**在 func 目录根落 `[0,±k]` 参数类型槽。 -2. `/lib/·.src`——源码副本(kind `char`)。 +2. `/lib/·.src`——源码副本(langtype `[]char/utf8`,storetype ARRAYND)。 3. 每个参数定义键——`funcDir.[0,-j]`(读参)/ `funcDir.[0,+j]`(写参),点后缀、与坐标斜杠键 - `/[0,±j]` 不同名;langtype=`def langtype`,body = 参数名 + NUL + 该参类型串。此键是**签名元数 + `/[0,±j]` 不同名;langtype=`def langtype`,body = 参数名 + NUL + 该参的 def langtype(匹配类型)串。此键是**签名元数 据**(dump / 类型检查 / 调用期类型检查用),**不参与运行时形参解析**——函数体指令里的形参引用 - 已在编译期替换为帧坐标的显式解引用 `*[0,-j]`/`*[0,+j]`,运行期直接读帧槽解引用到实参值(见 - [[调用extindex]])。 + 已在编译期替换为帧坐标:值参 `[0,±j]` 只读、地址参(声明带 `*`/`@`)`*[0,±j]` 解引用(也只读)—— + 读参(`param<0`)一律不得作写槽(见 [[函数]]、[[调用extindex]])。 4. 指令体从 `[1,0]` 起(`[0,0]` 为签名行锚点)。 func 目录根之所以**不**预落 `[0,±k]`:这些坐标是 runtime 调用期写入的帧本地实参地址;若 layout 提前 diff --git "a/stdlib/kvlang/spec/04-layout\350\257\255\344\271\211/07-layout\346\265\201\346\260\264\347\272\277.kv" "b/stdlib/kvlang/spec/04-layout\350\257\255\344\271\211/07-layout\346\265\201\346\260\264\347\272\277.kv" index e4df20bb..025e1250 100644 --- "a/stdlib/kvlang/spec/04-layout\350\257\255\344\271\211/07-layout\346\265\201\346\260\264\347\272\277.kv" +++ "b/stdlib/kvlang/spec/04-layout\350\257\255\344\271\211/07-layout\346\265\201\346\260\264\347\272\277.kv" @@ -35,8 +35,9 @@ kvspace 的 `/lib/` 子树,供 runtime 解释执行。layout 是 **o0 编译 1. 推断类型并特化算子。 2. `del_tree` 本函数目录(增量覆盖,仅本函数子树)。 -3. 写 `[0,0]` 签名锚点(langtype `rwfunc`,body `[nr][nw][dynamic]`)、签名行 `[0,x]` 各参数槽 - (`def langtype` xvalue,body=参数 langtype 串)、`.src` 源码副本、各命名参数 Ptr。 +3. 写 `[0,0]` 签名锚点(langtype `rwfunc`,body `[nr][nw][dynamic]`)、`.src` 源码副本、各**参数定义 + 键** `funcDir.[0,±j]`(`def langtype` xvalue,body=参数名 + NUL + 该参的 def langtype 串)。func 目录根不落 + `[0,±k]` 坐标槽(那些坐标留给 runtime 调用期写实参槽,见 [[函数写槽与布局]])。 4. 从 `[1,0]` 起写线性指令;goto/br 标签解析为整数 irseq。 5. 若有标签,写 `‥labels/