diff --git a/.gitignore b/.gitignore index c4c6d33..2e595ac 100644 --- a/.gitignore +++ b/.gitignore @@ -84,3 +84,9 @@ kvtut* # runtime-rs 测试 shm 产物 kvlangtest* + +# shm 测试残留(相对路径 DSN 标记 + slotsboxmalloc 后端文件) +/tut +/wptest +*.sbo.data +*.sbo.head diff --git a/deps.json b/deps.json index e3783f0..3319f42 100644 --- a/deps.json +++ b/deps.json @@ -1,7 +1,7 @@ { - "kvspace": "v0.2.12", - "kvspace-c": "v0.2.12", - "kvspace-durable": "v0.2.12", + "kvspace": "v0.2.13", + "kvspace-c": "v0.2.13", + "kvspace-durable": "v0.2.13", "blockmalloc": "v0.1.4", "slotsboxmalloc": "v0.1.5" } diff --git a/layout/src/code.rs b/layout/src/code.rs index bdf12f0..9179603 100644 --- a/layout/src/code.rs +++ b/layout/src/code.rs @@ -401,28 +401,20 @@ pub fn write_func(kv: &mut Kv, pkg: &str, fn_: &mut Func) { keytree::lib_src(pkg, &fn_.sig.name), ffi::new_char_byte(fn_.full_text().as_bytes()), )); - // 签名行:每个参数的类型定义落 [0,x] 槽(def langtype),x<0 读参、x>0 写参。 - // 运行期 call 会用实参绑定覆盖同坐标的帧槽,静态类型定义仅供 layout 类型检查/dump。 + // 命名参数键 funcDir/:Ptr,body=帧坐标 [0,±k](k<0 读参、k>0 写参), + // target_langtype=该参类型——类型随参数名承载。func dir 根不落 [0,±k] 静态槽: + // 那些坐标是 runtime call 期写入的帧本地实参地址,若 layout 提前落在 func dir 根, + // 建帧 extindex 时会把它们当只读扩展节点,令 call 期同坐标绑定触发 ext-write 保护。 for (i, p) in fn_.sig.params.iter().enumerate() { - let slot = format!("[0,-{}]", i + 1); - pairs.push(( - format!("{func_dir}/{slot}"), - kvkind::new_def_langtype(¶m_types[i]), - )); pairs.push(( format!("{func_dir}/{}", p.name), - ffi::new_ptr(kvkind::KIND_CHAR, &slot), + ffi::new_ptr(¶m_types[i], &format!("[0,-{}]", i + 1)), )); } for (i, r) in fn_.sig.returns.iter().enumerate() { - let slot = format!("[0,{}]", i + 1); - pairs.push(( - format!("{func_dir}/{slot}"), - kvkind::new_def_langtype(¶m_types[nr as usize + i]), - )); pairs.push(( format!("{func_dir}/{}", r.name), - ffi::new_ptr(kvkind::KIND_CHAR, &slot), + ffi::new_ptr(¶m_types[nr as usize + i], &format!("[0,{}]", i + 1)), )); } let _ = kv.set(&pairs); diff --git a/runtime-rs/src/engine.rs b/runtime-rs/src/engine.rs index f2a02bc..e632959 100644 --- a/runtime-rs/src/engine.rs +++ b/runtime-rs/src/engine.rs @@ -29,7 +29,7 @@ fn storetype_from_langtype(kx: &str) -> u8 { if base == "extindex" { return STORETYPE_EXTINDEX; } - if matches!(base, "index" | "rwfunc" | "defrwir") + if matches!(base, "index" | "rwfunc" | "def rwir") || base.starts_with('/') || base.contains('\u{b7}') { diff --git a/runtime-rwirext_example/go/json/json.go b/runtime-rwirext_example/go/json/json.go index dc2eb2f..9c835b6 100644 --- a/runtime-rwirext_example/go/json/json.go +++ b/runtime-rwirext_example/go/json/json.go @@ -646,14 +646,30 @@ type op struct { var myrwircaps []op +func cstrArr(n int) (**C.char, []*C.char) { + if n == 0 { + return nil, nil + } + arr := make([]*C.char, n) + for i := range arr { + arr[i] = cstr("any") + } + return (**C.char)(unsafe.Pointer(&arr[0])), arr +} + func register(c unsafe.Pointer) { for _, o := range myrwircaps { - sig := strings.TrimSuffix(strings.Repeat("any\n", o.nr+o.nw), "\n") co := cstr(o.name) - cs := cstr(sig) - C.kvlangRwirextRegister(c, co, C.int32_t(o.nr), C.int32_t(o.nw), cs) + rp, ra := cstrArr(o.nr) + wp, wa := cstrArr(o.nw) + C.kvlangDefRwir(c, co, rp, C.int32_t(o.nr), wp, C.int32_t(o.nw)) C.free(unsafe.Pointer(co)) - C.free(unsafe.Pointer(cs)) + for _, p := range ra { + C.free(unsafe.Pointer(p)) + } + for _, p := range wa { + C.free(unsafe.Pointer(p)) + } } } diff --git a/runtime-rwirext_example/py/numpy/numpy.py b/runtime-rwirext_example/py/numpy/numpy.py index 09b1fe1..c4956fc 100644 --- a/runtime-rwirext_example/py/numpy/numpy.py +++ b/runtime-rwirext_example/py/numpy/numpy.py @@ -93,8 +93,10 @@ def _bind(): for fn in ("kvlangRwirextParams", "kvlangRwirextResolveRead", "kvlangRwirextResolveReadPath", "kvlangRwirextResolveWrite", "kvlangRwirextNextPc"): getattr(_rt, fn).restype = ctypes.c_void_p - _rt.kvlangRwirextRegister.restype = ctypes.c_int - _rt.kvlangRwirextRegister.argtypes = [ctypes.c_void_p, ctypes.c_char_p, ctypes.c_int32, ctypes.c_int32, ctypes.c_char_p] + _rt.kvlangDefRwir.restype = ctypes.c_int + _rt.kvlangDefRwir.argtypes = [ctypes.c_void_p, ctypes.c_char_p, + ctypes.POINTER(ctypes.c_char_p), ctypes.c_int32, + ctypes.POINTER(ctypes.c_char_p), ctypes.c_int32] _rt.kvlangRwirextParams.argtypes = [ctypes.c_void_p, ctypes.c_char_p] _rt.kvlangRwirextResolveRead.argtypes = [ctypes.c_void_p, ctypes.c_char_p, ctypes.c_int] _rt.kvlangRwirextResolveReadPath.argtypes = [ctypes.c_void_p, ctypes.c_char_p, ctypes.c_int] @@ -288,9 +290,14 @@ def read_arg(self, pc, i): # ── 注册五大类 ───────────────────────────────────────────────── def register(self): + def _arr(lst): + return (ctypes.c_char_p * len(lst))(*[s.encode() for s in lst]) for op, (nr, _) in OPS.items(): - _rt.kvlangRwirextRegister(self.kv, op.encode(), nr, 1, ("\n".join(["any"] * (nr + 1))).encode()) - _rt.kvlangRwirextRegister(self.kv, b"numpy.print", 1, 0, b"any...") + rp = _arr(["any"] * nr) + wp = _arr(["any"]) + _rt.kvlangDefRwir(self.kv, op.encode(), rp, nr, wp, 1) + rp = _arr(["any..."]) + _rt.kvlangDefRwir(self.kv, b"numpy.print", rp, 1, None, 0) def _handle(self, op, nr, fn, pc): params = _s(_rt.kvlangRwirextParams(self.kv, pc.encode())).split("\n") diff --git a/runtime/src/kvcpu.c b/runtime/src/kvcpu.c index cfb88a8..e1a1c10 100644 --- a/runtime/src/kvcpu.c +++ b/runtime/src/kvcpu.c @@ -403,15 +403,11 @@ static char *handle_call(kvlangKv_t *kv, const char *pc, kvlangRwirInst_t *inst) const uint8_t *sbody = sig.data + h.body_offset; int nr = sbody[0] | (sbody[1] << 8); int nw = sbody[2] | (sbody[3] << 8); - int dyn = h.body_len >= 5 ? sbody[4] : 0; - - { /* 读参类型校验:reads[0]=函数名,实参从 reads[1] 起。 - * 读参 langtype 逐条落签名行 [0,-i] 槽(def langtype),主槽 body 仅计数头。 */ - char *ds = join_read_sig(kv, func_dir.p, nr); - int crc = check_read_types(kv, vtid, pc, fn, ds, nr, dyn, inst->reads + 1, inst->nr - 1); - free(ds); - if (crc != 0) goto fail; - } + + /* rwfunc 不做派发期位置化读参校验:类型随命名参数键 funcDir/(Ptr 的 + * target_langtype)承载,函数体在帧内按名解析、各 native 算子在使用点自校验操作数 + * kind。位置化的有序签名校验(join_read_sig+check_read_types)是 rwir 的需求—— + * 跨 runtime 队列按位置收参,故仅 def rwir 路由路径保留(见本文件 m->def_sig)。 */ char *caller_fr = kvlangKeytreeFrameRoot(pc); int d = kvlangKeytreeFrameNum(pc); diff --git "a/stdlib/kvlang/spec/00-\345\257\274\350\250\200/01-\350\214\203\345\233\264\344\270\216\344\270\200\350\207\264\346\200\247.kv" "b/stdlib/kvlang/spec/00-\345\257\274\350\250\200/01-\350\214\203\345\233\264\344\270\216\344\270\200\350\207\264\346\200\247.kv" index fa654f4..7c8bd23 100644 --- "a/stdlib/kvlang/spec/00-\345\257\274\350\250\200/01-\350\214\203\345\233\264\344\270\216\344\270\200\350\207\264\346\200\247.kv" +++ "b/stdlib/kvlang/spec/00-\345\257\274\350\250\200/01-\350\214\203\345\233\264\344\270\216\344\270\200\350\207\264\346\200\247.kv" @@ -4,30 +4,41 @@ lib kvlang/spec/导言/范围与一致性 { ## 本规范的地位 -本规范是 kvlang 语言的**唯一事实源**。语言核心的任何设计或实现调整,一律**规范驱动**:先改本规范的相应条款及其锚定示例,再改实现,直至锚例在三后端全绿。规范与实现不符时,以规范为准,实现视为缺陷。 +本规范是 kvlang 语言的**唯一事实源**。语言核心的任何设计或实现调整,一律**规范驱动**:先改本规范的相 +应条款及其锚定示例,再改实现,直至锚例在三后端全绿。规范与实现不符时,以规范为准,实现视为缺陷。 -规范以 kvlang 自身书写(`.kv`),layout&run 后落进 `/lib/kvlang/spec/…`——规范即 KV 树里的数据,可被 kvlang 自解析与自校验。 +规范以 kvlang 自身书写(`.kv`),layout&run 后落进 `/lib/kvlang/spec/…`——规范即 KV 树里的数据,可被 +kvlang 自解析与自校验。 ## 范围 本规范界定 kvlang 语言本体: - **词法**(卷 01)——源码表示、词法单元、注释、标识符、字面量、运算符。 -- **kvspace 模型**(卷 02)——地址空间、寻址与命名、键系统与数组访问、指令布局格式、系统变量。kvspace 既是寻址空间也是内存空间,是 kvlang 的第一性前置概念,故前置于语义两卷。 -- **类型系统**(卷 03)——种类与定宽类型、langtype 签名类型表达式、数组形态、容器。类型跨 layout 与 runtime 两阶段,故独立成卷。 -- **layout 语义**(卷 04)——静态语义:语法检查与布局。layout 是 **o0 编译器**:做检查、布局与降级,**不做任何优化**(一旦优化即丢失高层语义,使扩展编译器无法按原语义在异构硬件上优化),可报诊断。 +- **kvspace 模型**(卷 02)——地址空间、寻址与命名、键系统与数组访问、指令布局格式、系统变量。kvspace + 既是寻址空间也是内存空间,是 kvlang 的第一性前置概念,故前置于语义两卷。 +- **类型系统**(卷 03)——种类与定宽类型、langtype 签名类型表达式、数组形态、容器。类型跨 layout 与 + runtime 两阶段,故独立成卷。 +- **layout 语义**(卷 04)——静态语义:语法检查与布局。layout 是 **o0 编译器**:做检查、布局与降级, + **不做任何优化**(一旦优化即丢失高层语义,使扩展编译器无法按原语义在异构硬件上优化),可报诊断。 - **runtime 语义**(卷 05)——动态语义:纯解释执行。 -- **编译器语义**(卷 06)——扩展编译器与核心的契约:前端算子/后端算子两层表示、后端绑定、算子版本化与 runtime 高版本优先。编译器本体不属语言核心(是计算引擎类扩展的组成),本卷只界定其与核心的契约。流水线上编译器介于 layout 与 runtime 之间(layout o0 → 编译器优化 → runtime 解释)。 +- **编译器语义**(卷 06)——扩展编译器与核心的契约:前端算子/后端算子两层表示、后端绑定、算子版本化与 + runtime 高版本优先。编译器本体不属语言核心(是计算引擎类扩展的组成),本卷只界定其与核心的契约。流 + 水线上编译器介于 layout 与 runtime 之间(layout o0 → 编译器优化 → runtime 解释)。 附录给出唯一权威文法;设计理由卷为非规范(non-normative)的动机说明。 ## 核心与扩展边界 -kvlang 是**小核心 + 扩展主导**的语言。本规范只界定语言核心必须保证的语义,以及核心与 rwir 兑现方之间的契约(def rwir 路由头与各 runtime 的 myrwircaps)。具体 runtime(numpy、fs、networld、gpu 等)提供的 rwir 实现不属本规范,由各 runtime 文档界定;kv 源码**不声明** rwir——`def rwir` 路由头由各 runtime 注册到 `/lib`,本规范只规定 kvlang 如何定位与调用 rwir、经 def rwir 路由兑现(见卷 05)。 +kvlang 是**小核心 + 扩展主导**的语言。本规范只界定语言核心必须保证的语义,以及核心与 rwir 兑现方之间 +的契约(def rwir 路由头与各 runtime 的 myrwircaps)。具体 runtime(numpy、fs、networld、gpu 等)提供 +的 rwir 实现不属本规范,由各 runtime 文档界定;kv 源码**不声明** rwir——`def rwir` 路由头由各 runtime +注册到 `/lib`,本规范只规定 kvlang 如何定位与调用 rwir、经 def rwir 路由兑现(见卷 05)。 ## 一致性 -**tutorial 套件即一致性测试。** 一个实现是否符合本规范,由 `tutorial/` 下的可运行 `.kv` 示例判定:三后端(shm / fs / redis)全部通过、输出逐字节一致,即为符合。 +**tutorial 套件即一致性测试。** 一个实现是否符合本规范,由 `tutorial/` 下的可运行 `.kv` 示例判定:三 +后端(shm / fs / redis)全部通过、输出逐字节一致,即为符合。 本规范每条 normative 条款应锚定至 tutorial 中至少一条示例。修改语言的流程恒为: 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 ac38e8c..1959a90 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" @@ -10,7 +10,8 @@ lib kvlang/spec/导言/规范用语与阅读约定 { - **应 / 不应**(should / should not)——存在正当理由时可偏离,但须权衡后果。 - **可**(may)——纯可选。 -未加此类限定词的陈述句为**事实性描述**(语言如此这般),同样是 normative 的。设计动机、历史与取舍一律归入非规范的**设计理由**卷,不混入正文条款。 +未加此类限定词的陈述句为**事实性描述**(语言如此这般),同样是 normative 的。设计动机、历史与取舍一 +律归入非规范的**设计理由**卷,不混入正文条款。 ## 阅读约定 diff --git "a/stdlib/kvlang/spec/01-\350\257\215\346\263\225/01-\346\272\220\347\240\201\347\273\223\346\236\204.kv" "b/stdlib/kvlang/spec/01-\350\257\215\346\263\225/01-\346\272\220\347\240\201\347\273\223\346\236\204.kv" index 519980b..3c3a4da 100644 --- "a/stdlib/kvlang/spec/01-\350\257\215\346\263\225/01-\346\272\220\347\240\201\347\273\223\346\236\204.kv" +++ "b/stdlib/kvlang/spec/01-\350\257\215\346\263\225/01-\346\272\220\347\240\201\347\273\223\346\236\204.kv" @@ -9,19 +9,24 @@ lib kvlang/spec/词法/源码结构 { ## 源码表示 -kvlang 源文件是一段 **UTF-8 字节序列**。词法分析按字节推进:ASCII 字节触发语法结构,其余多字节序列(如中文、`é`)作为普通字符原样穿过,出现在标识符、字符串与路径内部。 +kvlang 源文件是一段 **UTF-8 字节序列**。词法分析按字节推进:ASCII 字节触发语法结构,其余多字节序列 +(如中文、`é`)作为普通字符原样穿过,出现在标识符、字符串与路径内部。 -一处**行**由换行符 `\n`(U+000A)界定;`\r`(U+000D)在词法阶段被直接跳过,不产生任何词法单元,故 `\r\n` 与 `\n` 等价。位置以 1 起始的 `line`、`col` 计。 +一处**行**由换行符 `\n`(U+000A)界定;`\r`(U+000D)在词法阶段被直接跳过,不产生任何词法单元,故 +`\r\n` 与 `\n` 等价。位置以 1 起始的 `line`、`col` 计。 ## 空白与语句分隔 -空格 ` ` 与制表符 `\t` 是词法单元之间的分隔符,本身不产生词法单元;除用于分隔相邻词法单元外不具意义。 +空格 ` ` 与制表符 `\t` 是词法单元之间的分隔符,本身不产生词法单元;除用于分隔相邻词法单元外不具意 +义。 -**语句分隔**由换行符 `\n` 与分号 `;` 表达,二者语义等价,均产生一个 `Newline` 词法单元。词法器执行两条归并规则: +**语句分隔**由换行符 `\n` 与分号 `;` 表达,二者语义等价,均产生一个 `Newline` 词法单元。词法器执行两 +条归并规则: - 连续的语句分隔(多个换行/分号、含其间空白)**折叠**为单个 `Newline`; - 词法单元流开头的语句分隔被**抑制**,不产生 `Newline`。 -字符串与原始字符串字面量内部的物理换行**不**产生 `Newline`(它是字面量内容的一部分),但行号仍随之前进。 +字符串与原始字符串字面量内部的物理换行**不**产生 `Newline`(它是字面量内容的一部分),但行号仍随之前 +进。 "#### -> /lib/kvlang/spec/词法/源码结构 } diff --git "a/stdlib/kvlang/spec/01-\350\257\215\346\263\225/02-\350\257\215\346\263\225\345\215\225\345\205\203.kv" "b/stdlib/kvlang/spec/01-\350\257\215\346\263\225/02-\350\257\215\346\263\225\345\215\225\345\205\203.kv" index e325f5b..468e32e 100644 --- "a/stdlib/kvlang/spec/01-\350\257\215\346\263\225/02-\350\257\215\346\263\225\345\215\225\345\205\203.kv" +++ "b/stdlib/kvlang/spec/01-\350\257\215\346\263\225/02-\350\257\215\346\263\225\345\215\225\345\205\203.kv" @@ -25,13 +25,18 @@ kvlang 只有 **7 个词法关键字**,它们在词法阶段即被识别,不 return if else for while break continue ``` -其余在语言中具有特殊含义的词(`lib`、`rwir`、`rwfunc`、`in`、`any`、`None`、`true`、`false`、种类名如 `int64`/`float32`/`struct` 等)**不是**词法关键字:它们一律词法化为 `Ident`,其含义由 layout 阶段依上下文赋予。这类词称为**上下文词**。 +其余在语言中具有特殊含义的词(`lib`、`rwir`、`rwfunc`、`in`、`any`、`None`、`true`、`false`、种类名 +如 `int64`/`float32`/`struct` 等)**不是**词法关键字:它们一律词法化为 `Ident`,其含义由 layout 阶段 +依上下文赋予。这类词称为**上下文词**。 -`def` **不是** kvlang 关键字,kv 源码中永不出现:`def rwir`/`def struct`/`def langtype` 是 head 的 langtype 元层「定义节点」标记,只在 layout 之后(`def struct`、`def langtype`)或 runtime 注册时(`def rwir`)产生,与源码词法无关(见 [[langtype语义类型]])。 +`def` **不是** kvlang 关键字,kv 源码中永不出现:`def rwir`/`def struct`/`def langtype` 是 head 的 +langtype 元层「定义节点」标记,只在 layout 之后(`def struct`、`def langtype`)或 runtime 注册时 +(`def rwir`)产生,与源码词法无关(见 [[langtype语义类型]])。 ## 最长匹配 -词法分析遵循**最长匹配**(maximal munch):在每个位置,词法器取能构成合法词法单元的最长字符序列。特别地: +词法分析遵循**最长匹配**(maximal munch):在每个位置,词法器取能构成合法词法单元的最长字符序列。特 +别地: - 以数字开头的序列必为数值字面量,不会被识别为标识符; - `-` 后紧跟 `>` 构成 `->`,`<` 后紧跟 `<` 构成 `<<`,依此类推——双字符运算符优先于其单字符成分。 diff --git "a/stdlib/kvlang/spec/01-\350\257\215\346\263\225/03-\346\263\250\351\207\212.kv" "b/stdlib/kvlang/spec/01-\350\257\215\346\263\225/03-\346\263\250\351\207\212.kv" index 2ba251a..50d8942 100644 --- "a/stdlib/kvlang/spec/01-\350\257\215\346\263\225/03-\346\263\250\351\207\212.kv" +++ "b/stdlib/kvlang/spec/01-\350\257\215\346\263\225/03-\346\263\250\351\207\212.kv" @@ -16,7 +16,8 @@ kvlang 有两种注释,语法与 Rust 一致。**不存在** `#` 注释。 x = 42 // 这是行注释 ``` -行注释不消费其后的换行符,故一行末尾的行注释之后仍产生一个 `Newline` 语句分隔。行注释不嵌套:其内部的 `//`、`/*` 均无特殊含义。 +行注释不消费其后的换行符,故一行末尾的行注释之后仍产生一个 `Newline` 语句分隔。行注释不嵌套:其内部 +的 `//`、`/*` 均无特殊含义。 ## 块注释 @@ -37,6 +38,7 @@ x = 42 // 这是行注释 ## 注释的地位 -注释被词法化为 `Comment` 词法单元,在词法流中保留,但对程序语义无贡献——layout 阶段将其忽略。注释不是语句分隔符:其内部的换行不产生 `Newline`(块注释),行注释后的换行照常产生 `Newline`。 +注释被词法化为 `Comment` 词法单元,在词法流中保留,但对程序语义无贡献——layout 阶段将其忽略。注释不是 +语句分隔符:其内部的换行不产生 `Newline`(块注释),行注释后的换行照常产生 `Newline`。 "#### -> /lib/kvlang/spec/词法/注释 } diff --git "a/stdlib/kvlang/spec/01-\350\257\215\346\263\225/04-\346\240\207\350\257\206\347\254\246.kv" "b/stdlib/kvlang/spec/01-\350\257\215\346\263\225/04-\346\240\207\350\257\206\347\254\246.kv" index 4e1158a..44cab4f 100644 --- "a/stdlib/kvlang/spec/01-\350\257\215\346\263\225/04-\346\240\207\350\257\206\347\254\246.kv" +++ "b/stdlib/kvlang/spec/01-\350\257\215\346\263\225/04-\346\240\207\350\257\206\347\254\246.kv" @@ -5,7 +5,8 @@ lib kvlang/spec/词法/标识符 { ## 锚例 - `tutorial/01-basics/vars.kv`——标识符 `x`、`y`。 -- `tutorial/01-basics/kv_tree.kv`——绝对路径 `/tmp/kvt`、子键路径 `/tmp/kvt·data`、层级路径 `/tmp/kvt/a`,以及成员/方法 `kv·set`、`kv·get`。 +- `tutorial/01-basics/kv_tree.kv`——绝对路径 `/tmp/kvt`、子键路径 `/tmp/kvt·data`、层级路径 + `/tmp/kvt/a`,以及成员/方法 `kv·set`、`kv·get`。 ## 标识符 @@ -25,9 +26,13 @@ println("值 =", 变量数) 此决策使 kvlang 与 C99、Go、Python、Rust、TypeScript 在「允许 Unicode 标识符」上对齐。 -7 个词法关键字(`return if else for while break continue`)为保留字,不得用作标识符;其余上下文词(`lib`、`None`、`true`、`false`、种类名等)不保留,但用作普通标识符会遮蔽其上下文含义,不应如此使用。 +7 个词法关键字(`return if else for while break continue`)为保留字,不得用作标识符;其余上下文词 +(`lib`、`None`、`true`、`false`、种类名等)不保留,但用作普通标识符会遮蔽其上下文含义,不应如此使 +用。 -> 实现说明(非规范):当前词法器以「最长非分隔符字节串」切分标识符,未逐字符校验上述字母表,故比本节所述更宽松。分隔符集合为空白、`; , ( ) { } [ ] :`、成员分隔符 `·`,以及运算符字符 `+ - * % ! = < > & | ^`。 +> 实现说明(非规范):当前词法器以「最长非分隔符字节串」切分标识符,未逐字符校验上述字母表,故比本节 + 所述更宽松。分隔符集合为空白、`; , ( ) { } [ ] :`、成员分隔符 `·`,以及运算符字符 + `+ - * % ! = < > & | ^`。 ## 成员分隔符 diff --git "a/stdlib/kvlang/spec/01-\350\257\215\346\263\225/05-\347\273\235\345\257\271\350\267\257\345\276\204\345\255\227\351\235\242\351\207\217.kv" "b/stdlib/kvlang/spec/01-\350\257\215\346\263\225/05-\347\273\235\345\257\271\350\267\257\345\276\204\345\255\227\351\235\242\351\207\217.kv" index 6af8fba..0ee4282 100644 --- "a/stdlib/kvlang/spec/01-\350\257\215\346\263\225/05-\347\273\235\345\257\271\350\267\257\345\276\204\345\255\227\351\235\242\351\207\217.kv" +++ "b/stdlib/kvlang/spec/01-\350\257\215\346\263\225/05-\347\273\235\345\257\271\350\267\257\345\276\204\345\255\227\351\235\242\351\207\217.kv" @@ -2,7 +2,8 @@ lib kvlang/spec/词法/绝对路径字面量 { r####"# 绝对路径字面量 -绝对路径直接寻址 kvspace 树中的节点,是一类字面量(词法化为以 `/` 起始的 `Literal`)。路径以 `/` 开头,后随一个 ASCII 字母、数字或下划线,随后是由下列成分构成的最长序列: +绝对路径直接寻址 kvspace 树中的节点,是一类字面量(词法化为以 `/` 起始的 `Literal`)。路径以 `/` 开 +头,后随一个 ASCII 字母、数字或下划线,随后是由下列成分构成的最长序列: - `/`——段分隔符,划分树的层级; - `.`——子键分隔符,寻址同一节点下的子键; @@ -15,6 +16,7 @@ kv·get("/tmp/kvt", "data") -> x kv·set("/tmp/kvt/a", 1) ``` -路径的完整寻址语义见 [[寻址与命名]];本节只界定其词法形态。裸 `/`(其后不接字母/数字/下划线,且非 `//`、`/*`)不构成路径,见 [[运算符基础]]。 +路径的完整寻址语义见 [[寻址与命名]];本节只界定其词法形态。裸 `/`(其后不接字母/数字/下划线,且非 +`//`、`/*`)不构成路径,见 [[运算符基础]]。 "#### -> /lib/kvlang/spec/词法/绝对路径字面量 } diff --git "a/stdlib/kvlang/spec/01-\350\257\215\346\263\225/06-\345\255\227\351\235\242\351\207\217\345\237\272\347\241\200.kv" "b/stdlib/kvlang/spec/01-\350\257\215\346\263\225/06-\345\255\227\351\235\242\351\207\217\345\237\272\347\241\200.kv" index 1a956a6..726e463 100644 --- "a/stdlib/kvlang/spec/01-\350\257\215\346\263\225/06-\345\255\227\351\235\242\351\207\217\345\237\272\347\241\200.kv" +++ "b/stdlib/kvlang/spec/01-\350\257\215\346\263\225/06-\345\255\227\351\235\242\351\207\217\345\237\272\347\241\200.kv" @@ -2,7 +2,8 @@ lib kvlang/spec/词法/字面量基础 { r####"# 字面量基础 -字面量是源码中直接书写的常量值。kvlang 有四类字面量:数值、字符串、绝对路径(词法见 [[标识符]]),以及上下文空/布尔字面量。 +字面量是源码中直接书写的常量值。kvlang 有四类字面量:数值、字符串、绝对路径(词法见 [[标识符]]),以 +及上下文空/布尔字面量。 ## 锚例 @@ -22,9 +23,11 @@ float = integer [ "." integer ] [ ("e" | "E") [ "+" | "-" ] integer ] ``` - 整数为一串十进制数字。**无**十六进制、八进制、二进制前缀,**无**下划线数字分隔符。 -- 浮点数为整数部分后可选跟小数部分 `.digits` 与可选指数 `(e|E)[±]digits`。小数点前必须有数字(不支持 `.5` 这类前导点写法)。 +- 浮点数为整数部分后可选跟小数部分 `.digits` 与可选指数 `(e|E)[±]digits`。小数点前必须有数字(不支持 + `.5` 这类前导点写法)。 - 数值字面量本身**无符号**;负数由前缀一元运算符 `-` 与字面量组合而成(见 [[运算符基础]])。 -`3` 是整数字面量,`3.14`、`6.28`、`1e3`、`2.5E-4` 是浮点字面量。字面量到具体定宽种类的落定由类型系统与上下文决定(见 [[种类与定宽类型]])。 +`3` 是整数字面量,`3.14`、`6.28`、`1e3`、`2.5E-4` 是浮点字面量。字面量到具体定宽种类的落定由类型系统 +与上下文决定(见 [[种类与定宽类型]])。 "#### -> /lib/kvlang/spec/词法/字面量基础 } diff --git "a/stdlib/kvlang/spec/01-\350\257\215\346\263\225/07-\345\255\227\347\254\246\344\270\262\344\270\216\347\251\272\345\200\274\345\270\203\345\260\224\345\255\227\351\235\242\351\207\217.kv" "b/stdlib/kvlang/spec/01-\350\257\215\346\263\225/07-\345\255\227\347\254\246\344\270\262\344\270\216\347\251\272\345\200\274\345\270\203\345\260\224\345\255\227\351\235\242\351\207\217.kv" index 667f99a..073e0ee 100644 --- "a/stdlib/kvlang/spec/01-\350\257\215\346\263\225/07-\345\255\227\347\254\246\344\270\262\344\270\216\347\251\272\345\200\274\345\270\203\345\260\224\345\255\227\351\235\242\351\207\217.kv" +++ "b/stdlib/kvlang/spec/01-\350\257\215\346\263\225/07-\345\255\227\347\254\246\344\270\262\344\270\216\347\251\272\345\200\274\345\270\203\345\260\224\345\255\227\351\235\242\351\207\217.kv" @@ -21,7 +21,8 @@ t = "one\ntwo" // 转义换行 ### 原始串 `r"…"` / `r#"…"#` / `r##"…"##` … -以 `r` 引导,**零转义**、可跨行。可在 `r` 与首个 `"` 之间加 `N` 个井号 `#`,此时须以 `"` 后接同样 `N` 个 `#` 闭合;井号越多可嵌套越深,内容因而能包含 `"`: +以 `r` 引导,**零转义**、可跨行。可在 `r` 与首个 `"` 之间加 `N` 个井号 `#`,此时须以 `"` 后接同样 +`N` 个 `#` 闭合;井号越多可嵌套越深,内容因而能包含 `"`: ``` r = r"raw\nliteral" // 输出含反斜杠与 n,非换行 @@ -30,13 +31,16 @@ q = r#"he said "hi""# // 内容含双引号 ### 单引号形式 `'…'` -以单引号界定,用于 char / keypath 场景,与转义串共享同一套转义规则。其内容作为裸字面量交由后续阶段依上下文(char 种类、键路径)解释。 +以单引号界定,用于 char / keypath 场景,与转义串共享同一套转义规则。其内容作为裸字面量交由后续阶段依 +上下文(char 种类、键路径)解释。 -kvlang 的动态字符串阵营中,单个字符通常以**长度为 1 的字符串**表示(如 `s[i]` 读返单字符字符串),char 的定宽种类见 [[种类与定宽类型]]。 +kvlang 的动态字符串阵营中,单个字符通常以**长度为 1 的字符串**表示(如 `s[i]` 读返单字符字符串), +char 的定宽种类见 [[种类与定宽类型]]。 ## 空值与布尔字面量 -- `None`——空值字面量。kvlang 的空值**只有** `None`;书写 `null` 是错误,layout **必须**显式拒绝,**不得**当作裸标识符静默放行。未赋值的变量地址即读作 `None`。 +- `None`——空值字面量。kvlang 的空值**只有** `None`;书写 `null` 是错误,layout **必须**显式拒绝,** + 不得**当作裸标识符静默放行。未赋值的变量地址即读作 `None`。 - `true` / `false`——布尔字面量。 三者均为**上下文词**:词法阶段化为标识符,由 layout/runtime 依类型上下文解释为对应值。 diff --git "a/stdlib/kvlang/spec/01-\350\257\215\346\263\225/08-\350\277\220\347\256\227\347\254\246\345\237\272\347\241\200.kv" "b/stdlib/kvlang/spec/01-\350\257\215\346\263\225/08-\350\277\220\347\256\227\347\254\246\345\237\272\347\241\200.kv" index 0055145..5bdefb5 100644 --- "a/stdlib/kvlang/spec/01-\350\257\215\346\263\225/08-\350\277\220\347\256\227\347\254\246\345\237\272\347\241\200.kv" +++ "b/stdlib/kvlang/spec/01-\350\257\215\346\263\225/08-\350\277\220\347\256\227\347\254\246\345\237\272\347\241\200.kv" @@ -2,7 +2,8 @@ lib kvlang/spec/词法/运算符基础 { r####"# 运算符基础 -本节界定运算符与方向记号的**词法**:有哪些符号、各写作什么字形。其求值与结合语义见 [[指令架构]]与 [[执行模型]]。符号表是权威的双向查找表,其余部分不得另行硬编码符号字符串。 +本节界定运算符与方向记号的**词法**:有哪些符号、各写作什么字形。其求值与结合语义见 [[指令架构]]与 +[[执行模型]]。符号表是权威的双向查找表,其余部分不得另行硬编码符号字符串。 ## 锚例 @@ -15,7 +16,8 @@ lib kvlang/spec/词法/运算符基础 { kvlang 有两种赋值/方向记号,均词法化为 `Arrow`: -- `->`——写右(数据从左流向右)。**契合参数轴布局**:读参在负轴、写参在正轴,箭头方向即数据流方向(负轴读入 → 零轴执行 → 正轴写出),与数学坐标系「负 → 正」直觉一致,详见 [[指令架构]]。 +- `->`——写右(数据从左流向右)。**契合参数轴布局**:读参在负轴、写参在正轴,箭头方向即数据流方向(负 + 轴读入 → 零轴执行 → 正轴写出),与数学坐标系「负 → 正」直觉一致,详见 [[指令架构]]。 - `=`——写左。**沿用主流编程语言习惯**(左写、右读),便于带着 C/Python/Rust/Go/JS 直觉的使用者上手。 ``` @@ -23,7 +25,8 @@ x = 42 // 左写、右读 42 -> x // 左读、右写 ``` -`=` 仅为写入记号,kvlang **无**独立的等号赋值语义之外用法;相等比较写作 `==`。**无 `<-`**:历史上有第三种 `<-`(写入左侧),与 `=` 完全重复,已删除——写入左侧一律写 `=`。 +`=` 仅为写入记号,kvlang **无**独立的等号赋值语义之外用法;相等比较写作 `==`。**无 `<-`**:历史上有 +第三种 `<-`(写入左侧),与 `=` 完全重复,已删除——写入左侧一律写 `=`。 ## 算术运算符 @@ -38,7 +41,8 @@ x = 42 // 左写、右读 **乘法是 `×`、除法是 `÷`**,非 ASCII 的 `*` 与 `/`: - `*`(U+002A)**不是**乘号。它在符号表中登记为 `pointer`,非算术运算符。 -- `/`(U+002F)**不是**除号。它只用于绝对路径字面量与注释(`//`、`/*`);出现在其他位置的裸 `/` 不承载算术除法语义。 +- `/`(U+002F)**不是**除号。它只用于绝对路径字面量与注释(`//`、`/*`);出现在其他位置的裸 `/` 不承 + 载算术除法语义。 一元 `+`、`-` 作前缀;`√`(U+221A,平方根)亦为一元前缀运算符。 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 23491f2..5ca65a4 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" @@ -37,6 +37,7 @@ lib kvlang/spec/词法/逻辑位运算与优先级 { ## 运算符成员分隔符 -`·`(U+00B7)是成员/方法分隔符,非算术运算符,词法化为独立的 `Dot` 词法单元,其词法与用途见 [[标识符]]。 +`·`(U+00B7)是成员/方法分隔符,非算术运算符,词法化为独立的 `Dot` 词法单元,其词法与用途见 [[标识 +符]]。 "#### -> /lib/kvlang/spec/词法/逻辑位运算与优先级 } 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 eb52022..a2ea62a 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" @@ -2,7 +2,9 @@ lib kvlang/spec/kvspace模型/地址空间 { r####"# 地址空间 -kvspace 是 kvlang 的第一性前置概念:它**既是寻址空间也是内存空间**。程序计数器 PC 是一条 kvspace 路径字符串,指令是路径上的值,变量是路径上的值,代码与数据统一在同一棵 KV 树上。本卷其余各章([[寻址与命名]]、[[键系统与数组访问]]、[[指令布局格式]]、[[系统变量]])均以本章界定的地址空间为基础。 +kvspace 是 kvlang 的第一性前置概念:它**既是寻址空间也是内存空间**。程序计数器 PC 是一条 kvspace 路 +径字符串,指令是路径上的值,变量是路径上的值,代码与数据统一在同一棵 KV 树上。本卷其余各章([[寻址与 +命名]]、[[键系统与数组访问]]、[[指令布局格式]]、[[系统变量]])均以本章界定的地址空间为基础。 ## 存储铁律 @@ -10,13 +12,16 @@ kvspace 是文件系统风格的键值抽象。任一条目由 key 与 value 构 - key **必须**是绝对、规范的字符串路径:以 `/` 开头,`/` 分隔层级;不得为相对路径。 - value **必须**是一个 XValue 序列化后的字节串(TLV 编码,格式见 [[键系统与数组访问]])。 -- **不得**向 kvspace 直接写入裸基础类型字节;所有值必须经 XValue 编解码。违反此铁律的写入,读取方在解码非法字节时行为未定义。 +- **不得**向 kvspace 直接写入裸基础类型字节;所有值必须经 XValue 编解码。违反此铁律的写入,读取方在 + 解码非法字节时行为未定义。 -目录以尾随 `/` 标记:key `/a/` 是目录(其 value 为 `index`),key `/a` 是普通值。同一路径的有尾斜杠与无尾斜杠形态可独立共存。 +目录以尾随 `/` 标记:key `/a/` 是目录(其 value 为 `index`),key `/a` 是普通值。同一路径的有尾斜杠 +与无尾斜杠形态可独立共存。 ## 扩展存储 -kvspace 元存中的 value 分两类:**内联数据**(基础类型、容器元数据)与**扩展存储句柄**。句柄 value 的 ref=2(@ext,见 [[键系统与数组访问]]),其 body 只记录目标位置描述符,真实字节位于元存之外: +kvspace 元存中的 value 分两类:**内联数据**(基础类型、容器元数据)与**扩展存储句柄**。句柄 value 的 +ref=2(@ext,见 [[键系统与数组访问]]),其 body 只记录目标位置描述符,真实字节位于元存之外: | 扩展位置 | 典型数据 | |---------|---------| @@ -24,10 +29,14 @@ kvspace 元存中的 value 分两类:**内联数据**(基础类型、容器 | GPU 显存 | 计算张量 | | 文件系统 / 对象存储 | 模型权重、检查点、数据集、外部进程输出 | -读取一个 ref=2 扩展句柄 value 时,运行时按 body 定位符前缀路由到对应兑现器还原真实字节(`runtime-rs/src/engine.rs`)。 +读取一个 ref=2 扩展句柄 value 时,运行时按 body 定位符前缀路由到对应兑现器还原真实字节 +(`runtime-rs/src/engine.rs`)。 ## 后端与前端 -kvspace 的 C ABI 由前端 dispatch 层(`kvspace` 仓 `src/frontend.c`)统一导出,运行期按连接串 scheme 选择后端:`shm://` 走 kvspace-c,`redis`/`fs`/`s3` 等走 kvspace-durable。三后端**必须**实现同一 ABI 与同一线格式(byte-identical),语义一致;一致性由 tutorial 三后端全绿判定(见 [[范围与一致性]])。ABI 符号与 XValue 线格式见 [[寻址与命名]] 与 [[键系统与数组访问]]。 +kvspace 的 C ABI 由前端 dispatch 层(`kvspace` 仓 `src/frontend.c`)统一导出,运行期按连接串 scheme +选择后端:`shm://` 走 kvspace-c,`redis`/`fs`/`s3` 等走 kvspace-durable。三后端**必须**实现同一 ABI +与同一线格式(byte-identical),语义一致;一致性由 tutorial 三后端全绿判定(见 [[范围与一致性]])。 +ABI 符号与 XValue 线格式见 [[寻址与命名]] 与 [[键系统与数组访问]]。 "#### -> /lib/kvlang/spec/kvspace模型/地址空间 } diff --git "a/stdlib/kvlang/spec/02-kvspace\346\250\241\345\236\213/02-\347\273\223\346\236\204\345\237\237.kv" "b/stdlib/kvlang/spec/02-kvspace\346\250\241\345\236\213/02-\347\273\223\346\236\204\345\237\237.kv" index a33ad3b..0c61cf5 100644 --- "a/stdlib/kvlang/spec/02-kvspace\346\250\241\345\236\213/02-\347\273\223\346\236\204\345\237\237.kv" +++ "b/stdlib/kvlang/spec/02-kvspace\346\250\241\345\236\213/02-\347\273\223\346\236\204\345\237\237.kv" @@ -2,7 +2,8 @@ lib kvlang/spec/kvspace模型/结构域 { r####"# 结构域 -kvspace 的路径中,只有以下前缀由语言核心赋予固定结构语义;其余 `/` 路径全部自由,由用户代码定义,核心不预设 schema。 +kvspace 的路径中,只有以下前缀由语言核心赋予固定结构语义;其余 `/` 路径全部自由,由用户代码定义,核 +心不预设 schema。 | 前缀 | 语义 | |------|------| @@ -10,22 +11,32 @@ kvspace 的路径中,只有以下前缀由语言核心赋予固定结构语义 | `/vthread` | 虚线程运行时状态:每 vthread 一棵子树,栈帧、PC、状态等随身系统变量暴露执行现场 | | `/networld` | 与外部世界交互的名册域:本机与外部进程、文件等以 `/networld/{host}/…` 登记,供 rwir(经 def rwir 路由)定位与兑现 | -`/lib` 与 `/vthread` 的前缀常量由运行时与 layout 各自定义(C 运行时 `runtime/src/runtime_internal.h` 的 `LIB_ROOT`/`VTHREAD_ROOT`,Rust layout `layout/src/keytree.rs` 的 `LIB_ROOT`/`VTHREAD_ROOT`)。 +`/lib` 与 `/vthread` 的前缀常量由运行时与 layout 各自定义(C 运行时 `runtime/src/runtime_internal.h` +的 `LIB_ROOT`/`VTHREAD_ROOT`,Rust layout `layout/src/keytree.rs` 的 `LIB_ROOT`/`VTHREAD_ROOT`)。 ### `/lib` -`/lib` 是全局命名空间,无 `import`——lib 树本身即命名空间。`lib name { … }` 块声明包;跨包调用走全路径 `/lib/{pkg}·{func}`。多文件经引导拼接后统一 layout 进 `/lib`,已加载条目去重。函数在 `/lib` 下只读,帧调用经 extindex 复用同一份指令树(见 [[指令布局格式]])。 +`/lib` 是全局命名空间,无 `import`——lib 树本身即命名空间。`lib name { … }` 块声明包;跨包调用走全路 +径 `/lib/{pkg}·{func}`。多文件经引导拼接后统一 layout 进 `/lib`,已加载条目去重。函数在 `/lib` 下只 +读,帧调用经 extindex 复用同一份指令树(见 [[指令布局格式]])。 ### `/vthread` -每个虚线程 `vid` 占一棵子树 `/vthread/{vid}/`,借用 Unix `/proc//` 思想:栈帧为其下的 KV 子树,`‥pc`、`‥status` 等系统变量(前缀 `‥`,见 [[系统变量]])暴露执行状态。PC 为路径字符串、帧根落 KV,故进程崩溃后可从 kvspace 续跑。 +每个虚线程 `vid` 占一棵子树 `/vthread/{vid}/`,借用 Unix `/proc//` 思想:栈帧为其下的 KV 子树, +`‥pc`、`‥status` 等系统变量(前缀 `‥`,见 [[系统变量]])暴露执行状态。PC 为路径字符串、帧根落 KV,故 +进程崩溃后可从 kvspace 续跑。 ### `/networld` -`/networld` 是本机在网络命名空间下的身份域,`host` 取裸 hostname。外部进程执行、宿主文件系统读写等**不**经设备文件,而是登记在 `/networld/{host}/…` 下并由 rwir(经 def rwir 路由)兑现:例如外部进程的 stdout/stderr 捕获为扩展存储句柄,其逻辑定位符形如 `/networld/{host}/proc/{pid}/{stream}`(`runtime-rs/src/rwir/networld/`)。 +`/networld` 是本机在网络命名空间下的身份域,`host` 取裸 hostname。外部进程执行、宿主文件系统读写等** +不**经设备文件,而是登记在 `/networld/{host}/…` 下并由 rwir(经 def rwir 路由)兑现:例如外部进程的 +stdout/stderr 捕获为扩展存储句柄,其逻辑定位符形如 `/networld/{host}/proc/{pid}/{stream}` +(`runtime-rs/src/rwir/networld/`)。 ### 没有设备域 -kvspace 世界中没有终端、没有设备文件,只有 key 与 value。`print`/`println` 等 I/O 不是地址空间的一个域,也不是核心内建,而是 rwir(以 def rwir 路由头注册于 `/lib/`,见 [[指令布局格式]]),执行时直接作用于宿主 I/O。 +kvspace 世界中没有终端、没有设备文件,只有 key 与 value。`print`/`println` 等 I/O 不是地址空间的一个 +域,也不是核心内建,而是 rwir(以 def rwir 路由头注册于 `/lib/`,见 [[指令布局格式]]),执行 +时直接作用于宿主 I/O。 "#### -> /lib/kvlang/spec/kvspace模型/结构域 } 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 81b5f33..88cc065 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" @@ -2,11 +2,13 @@ lib kvlang/spec/kvspace模型/寻址与命名 { r####"# 寻址与命名 -本章界定 kvlang 如何在 [[地址空间]] 上寻址:PC 的形态、变量名与指针的关系、路径分隔符语义,以及访问 kvspace 的 C ABI。 +本章界定 kvlang 如何在 [[地址空间]] 上寻址:PC 的形态、变量名与指针的关系、路径分隔符语义,以及访问 +kvspace 的 C ABI。 ## PC 是路径字符串 -传统 VM 的程序计数器是一维线性整数(内存地址),跳转与调用是整数算术。kvlang 的 PC 是一条 kvspace 路径字符串,跳转与调用是路径拼接与子树导航。 +传统 VM 的程序计数器是一维线性整数(内存地址),跳转与调用是整数算术。kvlang 的 PC 是一条 kvspace 路 +径字符串,跳转与调用是路径拼接与子树导航。 | 维度 | 传统 VM | kvlang | |------|---------|--------| @@ -16,11 +18,13 @@ lib kvlang/spec/kvspace模型/寻址与命名 { | 调用 | 压返回地址、跳入口 | 建帧子树、帧根 extindex 指向 `/lib` 指令树 | | 栈帧 | 连续内存 | `/vthread/{vid}/…` KV 子树 | -PC 落在 kvspace、帧根落在 kvspace,故执行现场可观测、可崩溃恢复。指令布局与帧机制见 [[指令布局格式]]。 +PC 落在 kvspace、帧根落在 kvspace,故执行现场可观测、可崩溃恢复。指令布局与帧机制见 [[指令布局格 +式]]。 ## 变量名即指针 -kvlang 没有取址运算符——**代码中变量的名字,本身就是该变量的指针**(一条 kvspace 路径)。指令槽里存的从来不是值,而是指针文本;求值恒经一次指针间接。指针有两种形态: +kvlang 没有取址运算符——**代码中变量的名字,本身就是该变量的指针**(一条 kvspace 路径)。指令槽里存的 +从来不是值,而是指针文本;求值恒经一次指针间接。指针有两种形态: | 形态 | 写法 | 语义 | 解析 | |------|------|------|------| @@ -33,15 +37,20 @@ kvlang 没有取址运算符——**代码中变量的名字,本身就是该 绝对路径 = FrameRoot(PC) + "/" + 相对指针 ``` -`FrameRoot(PC)` 从 PC 截去末尾的 `/[coord]` 指令坐标段即得帧根(`layout/src/keytree.rs` 的 `frame_root`:PC 无 `/[` 坐标段则为非法)。这与 C 的 `rbp + offset` 同构:帧根对应帧基址,相对指针对应栈偏移,绝对指针对应固定地址。 +`FrameRoot(PC)` 从 PC 截去末尾的 `/[coord]` 指令坐标段即得帧根(`layout/src/keytree.rs` 的 +`frame_root`:PC 无 `/[` 坐标段则为非法)。这与 C 的 `rbp + offset` 同构:帧根对应帧基址,相对指针对 +应栈偏移,绝对指针对应固定地址。 -`/lib` 下的函数模板中只有相对指针,因此天然可重入:每次调用产生不同的帧根,同一份相对指针拼接出互不干扰的绝对指针——递归与尾调用无需额外机制。 +`/lib` 下的函数模板中只有相对指针,因此天然可重入:每次调用产生不同的帧根,同一份相对指针拼接出互不 +干扰的绝对指针——递归与尾调用无需额外机制。 -**参数不得同名**:变量名即指针,同一帧内两个同名参数将指向同一 kvspace 位置。读参列表内、写参列表内、以及读写列表之间均**不得**同名;layout 静态阻断,运行时兜底。 +**参数不得同名**:变量名即指针,同一帧内两个同名参数将指向同一 kvspace 位置。读参列表内、写参列表 +内、以及读写列表之间均**不得**同名;layout 静态阻断,运行时兜底。 ## 路径分隔符 -kvspace 路径与 XValue 的 langtype 共用一套分隔符语义,每个分隔符承载固定含义(常量定义处:`kvspace/include/kvspace/const.h`、`kvspace-durable/src/const.rs`): +kvspace 路径与 XValue 的 langtype 共用一套分隔符语义,每个分隔符承载固定含义(常量定义处: +`kvspace/include/kvspace/const.h`、`kvspace-durable/src/const.rs`): | 分隔符 | 码位 | 语义 | |--------|------|------| @@ -50,6 +59,7 @@ kvspace 路径与 XValue 的 langtype 共用一套分隔符语义,每个分隔 | `‥` | U+2025 | 运行时系统变量前缀(`X/‥pc`,见 [[系统变量]]) | | `…` | U+2026 | extindex 句柄 body 的首元素前缀 | -标识符**不得**以 `‥` 开头,故用户代码永远造不出 `‥` 前缀段,系统变量命名空间与用户命名空间零交集(见 [[键系统与数组访问]] 的键形态三分)。 +标识符**不得**以 `‥` 开头,故用户代码永远造不出 `‥` 前缀段,系统变量命名空间与用户命名空间零交集(见 +[[键系统与数组访问]] 的键形态三分)。 "#### -> /lib/kvlang/spec/kvspace模型/寻址与命名 } 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 84c76ac..a54dcbb 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" @@ -2,9 +2,14 @@ lib kvlang/spec/kvspace模型/CABI { r####"# C ABI -**符号命名(normative)**:所有 C ABI 符号统一 `<前缀>` 无下划线(即 camelCase)——kvspace 层前缀 `kvspace`(`kvspaceGet` / `kvspaceWriteInPlace`),kvlang runtime 层前缀 `kvlang`(`kvlangRuntimeConnect` / `kvlangLangtypeParse`)。禁止下划线分词(不写 `kvspace_get` / `kvlang_runtime_connect`),头文件名可用下划线(`kvlang_runtime.h`),导出符号一律无下划线。 +**符号命名(normative)**:所有 C ABI 符号统一 `<前缀>` 无下划线(即 +camelCase)——kvspace 层前缀 `kvspace`(`kvspaceGet` / `kvspaceWriteInPlace`),kvlang runtime 层前缀 +`kvlang`(`kvlangRuntimeConnect` / `kvlangLangtypeParse`)。禁止下划线分词(不写 `kvspace_get` / +`kvlang_runtime_connect`),头文件名可用下划线(`kvlang_runtime.h`),导出符号一律无下划线。 -访问 kvspace 的唯一 C ABI 由前端 dispatch 静态导出(`kvspace/include/kvspace/kvspace.h`)。读写采用**借用指针模型**:读返回指向后端常驻空间的指针,调用方不得释放;写返回 body 偏移指针供调用方直接填。核心符号: +访问 kvspace 的唯一 C ABI 由前端 dispatch 静态导出(`kvspace/include/kvspace/kvspace.h`)。读写采用 +**借用指针模型**:读返回指向后端常驻空间的指针,调用方不得释放;写返回 body 偏移指针供调用方直接填。 +核心符号: | 符号 | 语义 | |------|------| @@ -21,9 +26,13 @@ lib kvlang/spec/kvspace模型/CABI { | `kvspaceClear` | 清空 | | `kvspaceWatch` | 一次性等待某 key 变为目标值 | -无句柄的编解码符号(前端静态实现,byte-identical):`kvspaceTlvEncode` / `kvspaceTlvEncodeMode` / `kvspaceDecodeHead`,以及构造器 `kvspaceNewPtr`(存目标完整 langtype + 目标 key)、`kvspaceNewChar` / `kvspaceNewBool` / `kvspaceNewInt64` / `kvspaceNewFloat64`。 +无句柄的编解码符号(前端静态实现,byte-identical):`kvspaceTlvEncode` / `kvspaceTlvEncodeMode` / +`kvspaceDecodeHead`,以及构造器 `kvspaceNewPtr`(存目标完整 langtype + 目标 key)、`kvspaceNewChar` +/ `kvspaceNewBool` / `kvspaceNewInt64` / `kvspaceNewFloat64`。 -读写各带 `resolve` 参数:`resolve=1` 时透明穿透 ref=1 指针(link);`kvspaceListLen`/`kvspaceListAt` 另有 `expand_ext` 参数控制是否展开 extindex 子项。head 线格式与 langtype 编码见 [[键系统与数组访问]]。 +读写各带 `resolve` 参数:`resolve=1` 时透明穿透 ref=1 指针(link);`kvspaceListLen`/`kvspaceListAt` +另有 `expand_ext` 参数控制是否展开 extindex 子项。head 线格式与 langtype 编码见 [[键系统与数组访 +问]]。 ## kvspace C ABI 导出符号全集(nm -D 实测,31) ``` 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 4513e72..cc27a2c 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" @@ -2,7 +2,8 @@ lib kvlang/spec/kvspace模型/键系统与数组访问 { r####"# 键系统与数组访问 -本章界定 kvspace 键的三种形态、XValue 的 langtype 类型表达与线格式、数组的两种物理存储形态及其访问方式。 +本章界定 kvspace 键的三种形态、XValue 的 langtype 类型表达与线格式、数组的两种物理存储形态及其访问方 +式。 ## 键形态三分 @@ -23,7 +24,8 @@ lib kvlang/spec/kvspace模型/键系统与数组访问 { | **kind** | 基础类型字符串(标量或元素类型),是 langtype 的叶子 | `uint8` `int32` `float64` `bool` `char/utf32` `stringkeymap` `rwir` `rwfunc` … | | **langtype** | 完整类型表达式串:可选 `[dims]` + kind;ref 已独立为 head 字节字段,不再是 langtype 前缀 | `int8` `[10]int32` `[256,256]uint8` `[]char/utf8·int64` | -kind 常量集中定义于 `kvspace/include/kvspace/const.h`(C)与 `kvspace-durable/src/const.rs`(Rust),两侧同名同值。剥掉 langtype 的所有前缀与 `[dims]` 修饰即得 kind。 +kind 常量集中定义于 `kvspace/include/kvspace/const.h`(C)与 `kvspace-durable/src/const.rs` +(Rust),两侧同名同值。剥掉 langtype 的所有前缀与 `[dims]` 修饰即得 kind。 ### langtype 文法 @@ -35,6 +37,10 @@ dims ::= '[' ']' # 变长一维 | '[' INT ( ',' INT )* ']' # 定长 / 多维(compact 连续布局) ``` -维数与各维长度编码进 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 串本身;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 串不含 `*`/`@` 前缀(见 [[总体方案]])。 "#### -> /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 15b6584..2e5811b 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" @@ -2,7 +2,9 @@ lib kvlang/spec/kvspace模型/XValueHead线格式 { r####"# XValueHead 线格式 -XValue = head + body。head 由三正交字段(ref × storetype × langtype)与辅助字段构成,langtype 串为语义类型真相(`kvspace/include/kvspace/kvspace.h`、`kvspace-c/src/xvalue.h`、`kvspace-durable/src/xvalue.rs`,三处 byte-identical): +XValue = head + body。head 由三正交字段(ref × storetype × langtype)与辅助字段构成,langtype 串为语 +义类型真相(`kvspace/include/kvspace/kvspace.h`、`kvspace-c/src/xvalue.h`、 +`kvspace-durable/src/xvalue.rs`,三处 byte-identical): ``` head = [headlen u16 LE][ref u8][storetype u8][ro u8][vid u32 LE][body_len u32 LE] @@ -21,8 +23,13 @@ body = [body_len B raw] | (storetype 物理字段) | 变 | ARRAYND:ndim u8 + dims[ndim] u32 LE;index/extindex:成员名 m×n 对齐字符串数组 dims=[len,cap,M](len=成员数、M align8、cap 预留容量);主槽 body 恒空 | | `langtype` | 变长 | 类型表达式串,占至 `headlen`(长度 = headlen − 当前偏移,无独立长度字段) | -`langtype` 恒为 head 最后一段,无独立长度字段;body 起始偏移 = `headlen`。ref 与 storetype 各为独立 u8 字节,不再编码进 langtype 串。ARRAYND 的 ndim、dims 直接读自 storetype 物理字段,与 langtype 串内 `[dims]` 保持同步(由 codec 保证)。`char/*` kind 恒为 ARRAYND(ndim=1)。None 编码:storetype=NONE、langtype=""、body 空。 +`langtype` 恒为 head 最后一段,无独立长度字段;body 起始偏移 = `headlen`。ref 与 storetype 各为独立 +u8 字节,不再编码进 langtype 串。ARRAYND 的 ndim、dims 直接读自 storetype 物理字段,与 langtype 串内 +`[dims]` 保持同步(由 codec 保证)。`char/*` kind 恒为 ARRAYND(ndim=1)。None 编码: +storetype=NONE、langtype=""、body 空。 -指针(ref=1)的 head langtype = 目标完整 langtype(langtype,含 `[dims]`),storetype = 目标 storetype,body = 目标 key 路径;由 `kvspaceNewPtr(target_langtype, target)` 构造,Set 时据此单跳类型检查。 +指针(ref=1)的 head langtype = 目标完整 langtype(langtype,含 `[dims]`),storetype = 目标 +storetype,body = 目标 key 路径;由 `kvspaceNewPtr(target_langtype, target)` 构造,Set 时据此单跳类 +型检查。 "#### -> /lib/kvlang/spec/kvspace模型/XValueHead线格式 } 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 3a0be01..ec46838 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" @@ -9,16 +9,27 @@ lib kvlang/spec/kvspace模型/数组两种物理形态 { | **compact** | 元素 kind(`int64`…) | `[1,2,3]`、`[N]T`、`[d0,d1]T` | 连续打包进单个 XValue 的 body | 1 | | **stringkeymap** | `stringkeymap` | `{v0,v1,…}`、`array·scatter` 等 | 每元素落独立子 key `base·[i]` | N+1 | -- **compact**:元素连续打包进一个 XValue,`raw_len = ∏dims × 元素字节宽`,head kind 即元素类型、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`)。 +- **compact**:元素连续打包进一个 XValue,`raw_len = ∏dims × 元素字节宽`,head kind 即元素类型、 + 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 元素的成员名是坐标段,物理 key 形如 `m·[i]`(一维)或 `m·[i,j]`(多维)——`·` 后紧跟方括号坐标,**不是** `m·0` 这类裸后缀。坐标段格式为 `[s0,s1,…]`:十进制、逗号分隔、无空格(`kvspace-durable/src/coord.rs` 的 `format_coord`)。 +stringkeymap 元素的成员名是坐标段,物理 key 形如 `m·[i]`(一维)或 `m·[i,j]`(多维)——`·` 后紧跟方括 +号坐标,**不是** `m·0` 这类裸后缀。坐标段格式为 `[s0,s1,…]`:十进制、逗号分隔、无空格 +(`kvspace-durable/src/coord.rs` 的 `format_coord`)。 -- 结构判定 `is_coord`:`[` 开头、`]` 结尾、内部不含嵌套 `[`/`]`;判定不要求整数(允许含点或字符串坐标)。 -- 排序 `cmp_coord`(row-major):坐标段恒排在非坐标段之前;两个可按整数解析的坐标段按数值升序,否则字典序。 -- 访问:源码 `m·[i]` 对散 key 元素走 `kv·get`(member 名 `[i]`);compact 的 `arr[i]` 走 `xv·at`。二者由括号与形态区分。 +- 结构判定 `is_coord`:`[` 开头、`]` 结尾、内部不含嵌套 `[`/`]`;判定不要求整数(允许含点或字符串坐 + 标)。 +- 排序 `cmp_coord`(row-major):坐标段恒排在非坐标段之前;两个可按整数解析的坐标段按数值升序,否则 + 字典序。 +- 访问:源码 `m·[i]` 对散 key 元素走 `kv·get`(member 名 `[i]`);compact 的 `arr[i]` 走 `xv·at`。二 + 者由括号与形态区分。 ## 字面量括号即形态 @@ -44,10 +55,15 @@ stringkeymap 元素的成员名是坐标段,物理 key 形如 `m·[i]`(一 | 1(ptr) | kvspace 内软链接 | 目标 key 路径 | | 2(@ext) | 扩展存储句柄 | 元存外位置描述符 | -ref=2 表示值本体在扩展世界(SHM/GPU/文件),head 中 langtype 记录形态(如 `[256,256]uint8`),body 记位置描述符。@ext 只表**单个值**存于扩展世界(compact 形态),与 storetype=index/extindex 无关。读取时按 body 前缀路由兑现(见 [[地址空间]] 扩展存储)。 +ref=2 表示值本体在扩展世界(SHM/GPU/文件),head 中 langtype 记录形态(如 `[256,256]uint8`),body +记位置描述符。@ext 只表**单个值**存于扩展世界(compact 形态),与 storetype=index/extindex 无关。读 +取时按 body 前缀路由兑现(见 [[地址空间]] 扩展存储)。 ## memindex:定宽目录矩阵 -storetype=index/extindex 的 head 物理字段记成员名 m×n 对齐字符串数组,参数 `dims=[len, cap, M]`,`M` 向上 8 对齐;`len` 为当前项数、`cap` 为预留容量、`M` 为行宽;主槽 body 恒空。`kvspaceMkindex` 带 `capacity` 参数、构造器 `kvspaceXvalueNewIndexGrow(children, count, cap_hint, m_hint)`(`kvspace-c/src/xvalue.h`)据此保留容量与行宽,使增删可就地覆写、不重分配。 +storetype=index/extindex 的 head 物理字段记成员名 m×n 对齐字符串数组,参数 `dims=[len, cap, M]`,`M` +向上 8 对齐;`len` 为当前项数、`cap` 为预留容量、`M` 为行宽;主槽 body 恒空。`kvspaceMkindex` 带 +`capacity` 参数、构造器 `kvspaceXvalueNewIndexGrow(children, count, cap_hint, m_hint)` +(`kvspace-c/src/xvalue.h`)据此保留容量与行宽,使增删可就地覆写、不重分配。 "#### -> /lib/kvlang/spec/kvspace模型/数组两种物理形态 } 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 834edc5..32bc116 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" @@ -2,11 +2,14 @@ lib kvlang/spec/kvspace模型/指令布局格式 { r####"# 指令布局格式 -本章界定函数经 layout 后在 `/lib` 下的 KV 布局:指令如何以坐标键落入 kvspace、签名与命名参数如何编码、调用如何经 extindex 复用指令树、参数如何经指针链解析。 +本章界定函数经 layout 后在 `/lib` 下的 KV 布局:指令如何以坐标键落入 kvspace、签名与命名参数如何编 +码、调用如何经 extindex 复用指令树、参数如何经指针链解析。 ## 空间布局,非线性字节码 -传统 VM 编译产线性字节码,调用即压返回地址后跳入口。kvlang 的 layout 不产线性序列,而是**空间布局**:每条指令展开为一组 `[s0,s1]` 坐标键,可逐槽 `kv·get`/`kv·list` 寻址,无需反汇编器。函数体永不被复制——调用时经 extindex 令帧根指向 `/lib` 下同一份指令树(见下 [[调用extindex]] 调用机制)。 +传统 VM 编译产线性字节码,调用即压返回地址后跳入口。kvlang 的 layout 不产线性序列,而是**空间布局 +**:每条指令展开为一组 `[s0,s1]` 坐标键,可逐槽 `kv·get`/`kv·list` 寻址,无需反汇编器。函数体永不被 +复制——调用时经 extindex 令帧根指向 `/lib` 下同一份指令树(见下 [[调用extindex]] 调用机制)。 ## 坐标键 `[s0,s1]` @@ -19,27 +22,39 @@ lib kvlang/spec/kvspace模型/指令布局格式 { ### 签名行 -函数目录 `/lib/{pkg}·{name}/` 自身(主槽):storetype = index、langtype = `rwfunc`(裸种类名,**不含签名**),body = `[nr:u16 LE][nw:u16 LE][dynamic:u8]`(读参个数 `nr`、写参个数 `nw`、是否变参 `dynamic`)。各参数真实类型**不**写进主槽 langtype,而落在**签名行 `[0,x]` 子槽**:`x<0` 读参、`x>0` 写参、`[0,0]` 为锚点;每个 `[0,x]`(`x≠0`)是 storetype=ARRAYND、langtype=`def langtype` 的 xvalue,body 为该参数完整 langtype 串(见 [[总体方案]])。同理,`def rwir` 目录主槽 langtype = `def rwir`(裸种类名),body 同格式,签名行 `[0,x]` 亦为 `def langtype` 子槽,无实现指令行。 +函数目录 `/lib/{pkg}·{name}/` 自身(主槽):storetype = index、langtype = `rwfunc`(裸种类名,**不含 +签名**),body = `[nr:u16 LE][nw:u16 LE][dynamic:u8]`(读参个数 `nr`、写参个数 `nw`、是否变参 +`dynamic`)。 -- 命名参数 → 槽映射:`/lib/{pkg}·{name}/{param}` 是一个 char/utf32 值,内容为该参数的槽坐标串(如 `x` → `"[0,-1]"`、返回值 `R` → `"[0,1]"`)。读参映射到 `[0,-j]`、写参映射到 `[0,+j]`。 +rwfunc 的各参数类型**不**落 `[0,x]` 静态槽,而随**命名参数键**承载:`/lib/{pkg}·{name}/{param}` 是一 +个 +Ptr,body 为该参数的槽坐标串(如 `x` → `"[0,-1]"`、返回值 `R` → `"[0,1]"`;读参 `[0,-j]`、写参 +`[0,+j]`),且 **Ptr 的 langtype 即该参数完整类型串**。rwfunc 按名在帧内解析、不在意参数顺序(仅区分 +读/写参),故 func 目录根**不**落 `[0,x]` 子槽。 + +`def rwir` 则相反:主槽 langtype = `def rwir`(裸种类名)、body 同计数格式,各参数类型落**位置化**签 +名 +行 `[0,x]` 子槽(`x<0` 读参、`x>0` 写参,storetype=ATOM、langtype=`def langtype`,body 为该参数 +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) -[0,-1] storetype=ARRAYND langtype=def langtype body="int64" ← 读参1 x 的类型 -[0,1] storetype=ARRAYND langtype=def langtype body="int64" ← 写参1 R 的类型 -x char/utf32→[0,-1] ← 命名读参 → 槽坐标(查表用) -R char/utf32→[0,1] ← 命名写参 → 槽坐标(查表用) -[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=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 ``` -opcode 槽 langtype 为 `rwir`(可为 `rwfunc` 引用),body 记 opcode 名。读/写槽的值有两类:`rwir:name` 是对变量的引用(存名字文本,即相对指针),或内联字面量(如 `int64:0`、`char/utf32:"…"`)。opcode 槽永不存变量引用,故值拷贝 `=` 与函数调用 `call` 在 KV 层无歧义。 +opcode 槽 langtype 为 `rwir`(可为 `rwfunc` 引用),body 记 opcode 名。读/写槽的值有两类: +`rwir:name` 是对变量的引用(存名字文本,即相对指针),或内联字面量(如 `int64:0`、 +`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 2ae7853..2966fc8 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" @@ -2,9 +2,14 @@ lib kvlang/spec/kvspace模型/调用extindex { r####"# 调用:extindex 复用指令树 -调用一个函数时,运行时**不**拷贝指令,而是为本次调用建帧子树,令帧根成为指向 `/lib/{pkg}·{name}/` 指令树的 extindex 叠加层,再把实参 / 结果地址写进帧根下的 `[0,±j]` 槽: - -- `/lib` 下只有命名参数键(如 `x`、`R`),坐标键 `[0,-j]` / `[0,+j]` 不存在;故运行时向 `frameRoot/[0,±j]` 写入不与只读指令树冲突。 +调用一个函数时,运行时**不**拷贝指令,而是为本次调用建帧子树,令帧根成为指向 `/lib/{pkg}·{name}/` 指 +令树的 extindex 叠加层,再把实参 / 结果地址写进帧根下的 `[0,±j]` 槽: + +- `/lib/{pkg}·{name}/` 下(rwfunc)只有命名参数键(`x` → body `"[0,-1]"`、langtype 为该参类型的 + Ptr),**无** `[0,±j]` 静态坐标槽。运行时向 `frameRoot/[0,±j]` 写实参地址 Ptr 时,该坐标在只读 + extindex 目标(函数树)中并不存在——extindex 写保护正因**该名在扩展层缺席而放行**帧本地写,实参内容 + 零拷贝。(反之若 layout 预落 `[0,±j]` 静态槽,写保护会因扩展层已有同名只读节点而拒写、丢参——故 + rwfunc 目录根不落这些坐标。) - 所有帧共享 `/lib` 下同一份指令树,零拷贝;帧根下叠加各自的实参槽与局部变量。 崩溃恢复由此自然成立:PC 是路径字符串、帧根落 KV、返回点落 KV——进程重启后可从 kvspace 续跑。 @@ -19,13 +24,18 @@ lib kvlang/spec/kvspace模型/调用extindex { 3. 读该路径 → 值 解引用 ``` -第 1 跳的 `frameRoot/x` 由 `/lib` 指令树经 extindex 透出(layout 写入、只读),第 2 跳的 `frameRoot/[0,-1]` 由运行时在调用点写入。读参地址可指向调用方值以实现零拷贝重定向(见 [[系统变量]] 的 `‥rparam` / `‥wparam`)。 +第 1 跳的 `frameRoot/x` 由 `/lib` 指令树经 extindex 透出(layout 写入、只读;其 Ptr 的 langtype 记参 +数类型,运行期解析只取 body 坐标),第 2 跳的 `frameRoot/[0,-1]` 由运行时在调用点写入。读参地址可指 +向 +调用方值以实现零拷贝重定向(见 [[系统变量]] 的 `‥rparam` / `‥wparam`)。 ## init 与标签 - lib 内的裸指令收集为隐式 `init` 函数(无 `init` 关键字),同样以上述布局落 `/lib/{pkg}·init/`。 -- 具名块的标签落 `/lib/{pkg}·{name}/‥labels/{label}` → 指令序号(`layout/src/code.rs`、`layout/src/keytree.rs`)。 +- 具名块的标签落 `/lib/{pkg}·{name}/‥labels/{label}` → 指令序号(`layout/src/code.rs`、 + `layout/src/keytree.rs`)。 -签名类型表达式文法见 [[文法]];帧的系统变量见 [[系统变量]];坐标键与 langtype 的分隔符语义见 [[键系统与数组访问]]。 +签名类型表达式文法见 [[文法]];帧的系统变量见 [[系统变量]];坐标键与 langtype 的分隔符语义见 [[键系 +统与数组访问]]。 "#### -> /lib/kvlang/spec/kvspace模型/调用extindex } 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 774bf4e..c68896d 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" @@ -2,9 +2,12 @@ lib kvlang/spec/kvspace模型/系统变量 { r####"# 系统变量 -运行时为它管理的对象附带**系统变量**(影子元数据),以 `{对象key}/‥{名}` 形式存放:宿主对象 `/` 下探一层、键名以 `‥`(U+2025)开头。标识符禁以 `‥` 开头,故所有 `‥` 前缀键均为核心保留,用户代码无法直接读写——类比 Unix 隐藏文件,默认视图不显示、引擎可见。 +运行时为它管理的对象附带**系统变量**(影子元数据),以 `{对象key}/‥{名}` 形式存放:宿主对象 `/` 下探 +一层、键名以 `‥`(U+2025)开头。标识符禁以 `‥` 开头,故所有 `‥` 前缀键均为核心保留,用户代码无法直接 +读写——类比 Unix 隐藏文件,默认视图不显示、引擎可见。 -系统变量(`X/‥名`,`/` + `‥` 前缀)与用户成员(`X·名`,`·` 中点键)正交,零交集(见 [[键系统与数组访问]] 键形态三分)。生命周期绑定:`X/‥*` 落在 X 的 `/` 子树内,删除 X 子树即连带清除其全部系统变量。 +系统变量(`X/‥名`,`/` + `‥` 前缀)与用户成员(`X·名`,`·` 中点键)正交,零交集(见 [[键系统与数组访 +问]] 键形态三分)。生命周期绑定:`X/‥*` 落在 X 的 `/` 子树内,删除 X 子树即连带清除其全部系统变量。 ## vthread 系统变量 @@ -36,18 +39,22 @@ lib kvlang/spec/kvspace模型/系统变量 { ## 函数标签 -具名作用域的标签不落在帧上,而落在函数的 `/lib` 定义处:`/lib/{pkg}·{name}/‥labels/{label}` → 指令序号(`layout/src/keytree.rs`、`layout/src/code.rs`)。 +具名作用域的标签不落在帧上,而落在函数的 `/lib` 定义处:`/lib/{pkg}·{name}/‥labels/{label}` → 指令序 +号(`layout/src/keytree.rs`、`layout/src/code.rs`)。 ## 语法层保留名 `._` -`._` 是源码层的丢弃槽占位符:写目标为 `._` 时不落 kvspace(帧槽键构造遇此名返回空路径)。它是语法占位符,**不**是 `‥` 系统变量,不落入 kvspace。 +`._` 是源码层的丢弃槽占位符:写目标为 `._` 时不落 kvspace(帧槽键构造遇此名返回空路径)。它是语法占 +位符,**不**是 `‥` 系统变量,不落入 kvspace。 ## `debugger()` -`debugger()` 内建对齐 V8/TypeScript 的 `debugger;` 语句:源码内联暂停点。非调试模式下为 no-op;调试模式下将 `‥status` 置 `paused`,由外部驱动改回 `running` 恢复执行。 +`debugger()` 内建对齐 V8/TypeScript 的 `debugger;` 语句:源码内联暂停点。非调试模式下为 no-op;调试 +模式下将 `‥status` 置 `paused`,由外部驱动改回 `running` 恢复执行。 ## 域与变量之别 -注意区分:[[地址空间]] 的结构**域**(`/lib`、`/vthread`、`/networld` 顶层树)与对象随身的 `‥` 系统**变量**是两种机制。域是路径前缀赋予的固定结构语义,系统变量是任一对象 `/` 子树内的影子元数据。 +注意区分:[[地址空间]] 的结构**域**(`/lib`、`/vthread`、`/networld` 顶层树)与对象随身的 `‥` 系统** +变量**是两种机制。域是路径前缀赋予的固定结构语义,系统变量是任一对象 `/` 子树内的影子元数据。 "#### -> /lib/kvlang/spec/kvspace模型/系统变量 } 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 9e211a9..ce7b28e 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" @@ -4,28 +4,36 @@ lib kvlang/spec/类型系统/种类与定宽类型 { kvlang 是**严格定宽类型语言**。 每个变量、参数、返回值都有确定的种类(kind);无无类型变量,运行时种类不隐式改变。 -类型信息随值自描述:每个 XValue 的类别由 head 三个正交字段表达(见 [[总体方案]] 与 [[XValueHead线格式]]): +类型信息随值自描述:每个 XValue 的类别由 head 三个正交字段表达(见 [[总体方案]] 与 [[XValueHead线格 +式]]): - `ref`(存储位置):0=inline、1=ptr(软链)、2=@ext(单值在扩展世界); - `storetype`(物理布局,codec 视角,闭合集:NONE/ATOM/ARRAYND/index/extindex); - `langtype`(语义类型,完整类型表达式串,变长,见 [[langtype签名类型表达式]])。 ## 锚例 -- 定宽构造与转换、float→int 截断、窄化回绕:`tutorial/01-basics/cast.kv`、`tutorial/01-basics/numtypes.kv`。 +- 定宽构造与转换、float→int 截断、窄化回绕:`tutorial/01-basics/cast.kv`、 + `tutorial/01-basics/numtypes.kv`。 - 算术保宽与混合提升:`tutorial/01-basics/type_narrowing.kv`。 - 字符编码与索引:`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/`。 +- 类型错误(bool 算术、跨种类比较、无符号取负、None、compact 变长串): + `tutorial/error_cases/type_error/`、`error_cases/none_type_error/`。 ## 数值运算域 -1. **同种类算术产生同种类结果**,溢出按补码回绕:`int8(127)+int8(1)`=-128、`uint8(255)+uint8(1)`=0、`int32(100)×int32(100)`=10000(kind 保持 `int32`)。float32 运算不升 float64:`float32(16777216)+float32(1)`=16777216.0。 -2. **混合宽度整数向更宽种类提升**:`int8(100)×int16(2)`=200(结果 `int16`);`int8(7)%int16(3)`=1(结果 `int16`)。 -3. **任一侧浮点则提升为浮点**:`int8(120)÷float32(10)`=12.0(结果 `float32`);两整数 `÷` 为整除(`int8(120)÷int8(10)`=12)。 +1. **同种类算术产生同种类结果**,溢出按补码回绕:`int8(127)+int8(1)`=-128、`uint8(255)+uint8(1)`=0、 + `int32(100)×int32(100)`=10000(kind 保持 `int32`)。float32 运算不升 float64: + `float32(16777216)+float32(1)`=16777216.0。 +2. **混合宽度整数向更宽种类提升**:`int8(100)×int16(2)`=200(结果 `int16`);`int8(7)%int16(3)`=1 + (结果 `int16`)。 +3. **任一侧浮点则提升为浮点**:`int8(120)÷float32(10)`=12.0(结果 `float32`);两整数 `÷` 为整除 + (`int8(120)÷int8(10)`=12)。 4. **无符号取负** `-(uint8 值)` TypeError(对齐 C 警告 / Rust、Go 编译错误)。 5. **bool 不参与算术**:`true + false` TypeError。 6. **None 参与算术** TypeError;**None 参与分支条件** TypeError。 -7. **跨种类比较** TypeError(`int64(5) == "hello"` 报错);数值种类之间可跨宽度比较(`3 == 3.0` 为 true)。 +7. **跨种类比较** TypeError(`int64(5) == "hello"` 报错);数值种类之间可跨宽度比较(`3 == 3.0` 为 + true)。 ## bool 铁律 @@ -38,8 +46,10 @@ kvlang 是**严格定宽类型语言**。 | 非空字符串 | TypeError——须显式写 `!= ""` | | None | TypeError | -分支条件(`if`/`while`/`br`)的条件槽**必须**是 `bool`。强制显式比较使控制流走向可被静态判定,不依赖运行时种类。 +分支条件(`if`/`while`/`br`)的条件槽**必须**是 `bool`。强制显式比较使控制流走向可被静态判定,不依赖 +运行时种类。 -逻辑运算 `&&`/`||`/`!` 的操作数**必须**是 `bool`,非 bool 即 TypeError;`bool(x)` 构造器只接受 `true`/`false`,其余种类 TypeError(对整数须写 `!= 0`)。 +逻辑运算 `&&`/`||`/`!` 的操作数**必须**是 `bool`,非 bool 即 TypeError;`bool(x)` 构造器只接受 +`true`/`false`,其余种类 TypeError(对整数须写 `!= 0`)。 "#### -> /lib/kvlang/spec/类型系统/种类与定宽类型 } 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 32eef7a..a53785c 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" @@ -18,7 +18,8 @@ kvlang 的数字种类**必须携带精确位宽**: ### 低精度浮点种类 -面向张量的低精度浮点种类。**位布局各不相同**(fp8 更有两种 OCP 格式),故与字符编码同理,种类名**必须显式带出具体格式**,**禁**裸 `float8`/`fp8`: +面向张量的低精度浮点种类。**位布局各不相同**(fp8 更有两种 OCP 格式),故与字符编码同理,种类名**必 +须显式带出具体格式**,**禁**裸 `float8`/`fp8`: | 种类 | 位布局 | 元素字节 | |------|--------|---------| @@ -27,9 +28,14 @@ kvlang 的数字种类**必须携带精确位宽**: | `float8/e4m3` | OCP FP8 E4M3 | 1B | | `float8/e5m2` | OCP FP8 E5M2 | 1B | -这些种类用于张量的**类型标注**:layout 认作合法基种类、可写进签名 langtype;runtime 只搬字节、按种类串相等匹配,**不实现**其算术——低精度运算由 deepx 系 runtime/后端兑现(fp8 的 per-tensor/block scale 亦不由 langtype 表达,属算子/张量元数据)。 +这些种类用于张量的**类型标注**:layout 认作合法基种类、可写进签名 langtype;runtime 只搬字节、按种类 +串相等匹配,**不实现**其算术——低精度运算由 deepx 系 runtime/后端兑现(fp8 的 per-tensor/block scale +亦不由 langtype 表达,属算子/张量元数据)。 -**铁律——无家族简写**。`int`、`uint`、`float`、`num`、`char` 这类不含位宽/编码的简写**不是**合法种类,在任何类型标注中均**不得**出现。位宽与字符编码是**开放集合**(如 `int4` 等仍未纳入),封闭的家族枚举必然漏项;纳入新位宽须逐个**显式命名**(如上表低精度浮点),多态则靠 [[langtype签名类型表达式]] 的显式 `|` 枚举表达(如 `int8|int16|int32|int64`、`float16|bfloat16`)。 +**铁律——无家族简写**。`int`、`uint`、`float`、`num`、`char` 这类不含位宽/编码的简写**不是**合法种 +类,在任何类型标注中均**不得**出现。位宽与字符编码是**开放集合**(如 `int4` 等仍未纳入),封闭的家族 +枚举必然漏项;纳入新位宽须逐个**显式命名**(如上表低精度浮点),多态则靠 [[langtype签名类型表达式]] +的显式 `|` 枚举表达(如 `int8|int16|int32|int64`、`float16|bfloat16`)。 ### bool 与字符种类 @@ -40,7 +46,10 @@ kvlang 的数字种类**必须携带精确位宽**: | `char/ascii` | ASCII 字节序列,1B×N,定宽、可索引 | | `char/utf8` | UTF-8 字节序列,1B×N,变宽、**禁索引**(仅存储与交换) | -字符三种编码的判定为前缀相等:某种类是字符种类当且仅当它以 `char/` 起始。定宽编码(`utf32`、`ascii`)**必须**支持 O(1) 码点索引;变宽编码 `utf8` 的按码点索引操作(`string·char`、`s[i]` 等)**必须**报 TypeError。单个字符标注为 `char/<编码>`(标量),字符串标注为 `[]char/<编码>`(序列);字符种类的值恒为一维序列。 +字符三种编码的判定为前缀相等:某种类是字符种类当且仅当它以 `char/` 起始。定宽编码(`utf32`、 +`ascii`)**必须**支持 O(1) 码点索引;变宽编码 `utf8` 的按码点索引操作(`string·char`、`s[i]` 等)** +必须**报 TypeError。单个字符标注为 `char/<编码>`(标量),字符串标注为 `[]char/<编码>`(序列);字符 +种类的值恒为一维序列。 ### 容器与结构种类 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 b300d6c..9fd6874 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,17 +6,28 @@ lib kvlang/spec/类型系统/种类_代码与特殊值 { 下列 langtype 描述 KV 树中的代码与目录节点(见 [[指令布局格式]]): -- `rwir`:无 kvlang 实现体,指令名文本,storetype=ARRAYND 叶子;由 runtime 经 def rwir 路由直接兑现。 -- `def rwir`:**路由头**,仅存于 `/lib/`,是 rwir 统一调度入口,storetype=index(定义节点),**无 kvlang 实现体**;**不叫"扩展算子"**,**不得**出现在用户书写的类型标注中。每个 runtime 只声明 **myrwircaps**(该 runtime 能兑现的 rwir 能力集);rwir 若不在本 runtime myrwircaps 内须经 `/lib/` 的 def rwir 路由给能兑现它的其它 runtime。 -- `rwfunc`:有 kvlang 实现体(`/` 目录下的指令槽序列),storetype=index(静态定义)或 extindex(vthread 运行栈),可被任意 main-runtime 直接解释执行。 +- `rwir`:无 kvlang 实现体,指令名文本,storetype=ARRAYND 叶子;由 runtime 经 def rwir 路由直接兑 + 现。 +- `def rwir`:**路由头**,仅存于 `/lib/`,是 rwir 统一调度入口,storetype=index(定义节点),** + 无 kvlang 实现体**;**不叫"扩展算子"**,**不得**出现在用户书写的类型标注中。每个 runtime 只声明 + **myrwircaps**(该 runtime 能兑现的 rwir 能力集);rwir 若不在本 runtime myrwircaps 内须经 + `/lib/` 的 def rwir 路由给能兑现它的其它 runtime。 +- `rwfunc`:有 kvlang 实现体(`/` 目录下的指令槽序列),storetype=index(静态定义)或 extindex + (vthread 运行栈),可被任意 main-runtime 直接解释执行。 -**故有 def rwir 而无 def rwfunc**:rwfunc 有 kvlang 实现体(一串 rwir),任意 main-runtime 逐条解释即可,无需路由头;rwir 无实现体,不在本 runtime myrwircaps 内时必须路由,故需 def rwir。 +**故有 def rwir 而无 def rwfunc**:rwfunc 有 kvlang 实现体(一串 rwir),任意 main-runtime 逐条解释 +即可,无需路由头;rwir 无实现体,不在本 runtime myrwircaps 内时必须路由,故需 def rwir。 ### None 与 ptr 不是种类 -- **None** 不是种类:它是 `storetype=NONE` 的空结构体 XValue。任何有名变量都有地址、都有 XValue;未赋值即 None。None 参与算术、比较、分支条件、类型构造一律 TypeError(见下文与 [[执行模型]])。 -- **ptr(软链接)** 不是种类:它是 head 的 `ref=1`(存储位置维),head 的 storetype/langtype 描述目标的完整形态,body 存目标 key 路径(见 [[容器]])。 +- **None** 不是种类:它是 `storetype=NONE` 的空结构体 XValue。任何有名变量都有地址、都有 XValue;未 + 赋值即 None。None 参与算术、比较、分支条件、类型构造一律 TypeError(见下文与 [[执行模型]])。 +- **ptr(软链接)** 不是种类:它是 head 的 `ref=1`(存储位置维),head 的 storetype/langtype 描述目 + 标的完整形态,body 存目标 key 路径(见 [[容器]])。 -> ptr(`ref=1`)是 head 的 ref 字段(存储位置维);kvlang **源码**类型标注最前仍可书写 `*`/`@` 前缀(如 `*int64`、`@[256,256]uint8`),表 ref,layout 解析时剥离该前缀落成 head `ref` 独立字节;**wire 层 langtype 串不含 `*`/`@` 前缀**,存储位置一律经 head `ref` 字节表达。extindex 是 storetype(物理布局维),与 ref=2 无关(见 [[总体方案]])。 +> ptr(`ref=1`)是 head 的 ref 字段(存储位置维);kvlang **源码**类型标注最前仍可书写 `*`/`@` 前缀 + (如 `*int64`、`@[256,256]uint8`),表 ref,layout 解析时剥离该前缀落成 head `ref` 独立字节; + **wire 层 langtype 串不含 `*`/`@` 前缀**,存储位置一律经 head `ref` 字节表达。extindex 是 + storetype(物理布局维),与 ref=2 无关(见 [[总体方案]])。 "#### -> /lib/kvlang/spec/类型系统/种类_代码与特殊值 } diff --git "a/stdlib/kvlang/spec/03-\347\261\273\345\236\213\347\263\273\347\273\237/04-\346\236\204\351\200\240\345\231\250.kv" "b/stdlib/kvlang/spec/03-\347\261\273\345\236\213\347\263\273\347\273\237/04-\346\236\204\351\200\240\345\231\250.kv" index bc08dd0..29fba3f 100644 --- "a/stdlib/kvlang/spec/03-\347\261\273\345\236\213\347\263\273\347\273\237/04-\346\236\204\351\200\240\345\231\250.kv" +++ "b/stdlib/kvlang/spec/03-\347\261\273\345\236\213\347\263\273\347\273\237/04-\346\236\204\351\200\240\345\231\250.kv" @@ -21,6 +21,7 @@ u = char/ascii(t) // 非 ASCII 码点 → TypeError | float32 精度 | 收窄至单精度(`float32(3.141592653589793)`=3.1415927、`float32(16777217)`=16777216.0) | | None 输入 | TypeError(`int64(None)` 报错,不得静默产生 0) | -构造器接受字面量与变量表达式(`42.9 -> x; int8(x)`)。种类构造的结果 XValue 以该种类名为 langtype 落入 kvspace,精度信息随值保留。 +构造器接受字面量与变量表达式(`42.9 -> x; int8(x)`)。种类构造的结果 XValue 以该种类名为 langtype 落 +入 kvspace,精度信息随值保留。 "#### -> /lib/kvlang/spec/类型系统/构造器 } 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 f91d317..67c528a 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" @@ -2,7 +2,9 @@ lib kvlang/spec/类型系统/langtype签名类型表达式 { r####"# langtype(两型与 kindexpr) -**langtype** 是 XValue head 的语义类型维(见 [[总体方案]]、[[head字段]]),逐字节是一段**类型表达式串**——base 种类、可选形状 `[dims]`、mapexpr、原型路径等(文法见 [[文法与合法性]])。它既供人和工具读写,也落入 kvspace 作运行期匹配依据,贯穿 layout(静态校验)与 runtime(值匹配),是类型的唯一真相。 +**langtype** 是 XValue head 的语义类型维(见 [[总体方案]]、[[head字段]]),逐字节是一段**类型表达式 +串**——base 种类、可选形状 `[dims]`、mapexpr、原型路径等(文法见 [[文法与合法性]])。它既供人和工具读 +写,也落入 kvspace 作运行期匹配依据,贯穿 layout(静态校验)与 runtime(值匹配),是类型的唯一真相。 ## langtype 两型:def langtype 与 value langtype @@ -10,28 +12,41 @@ lib kvlang/spec/类型系统/langtype签名类型表达式 { | 型 | 出现位置 | 角色 | 表达力 | |----|---------|------|--------| -| **def langtype** | rwfunc / `def rwir` 签名行 `[0,x]` 槽(storetype=`def langtype`,见 [[storetype_def族与签名行]]) | **模式**:描述一个参数「可接受的一类值」 | 完整——并集 `A\|B`、轴量词 `.`/`?`/`*`/`+`、`any`、mapexpr(见 [[匹配语义与变参]])。参数变参 `...` 是签名层 arity、**不在** langtype 内(见 [[函数]]) | +| **def langtype** | def rwir 签名行 `[0,x]` 槽(storetype=`def langtype`);rwfunc 则随命名参数键 `{name}` 的 Ptr langtype 承载同一模式(见 [[storetype_def族与签名行]]) | **模式**:描述一个参数「可接受的一类值」 | 完整——并集 `A\|B`、轴量词 `.`/`?`/`*`/`+`、`any`、mapexpr(见 [[匹配语义与变参]])。参数变参 `...` 是签名层 arity、**不在** langtype 内(见 [[函数]]) | | **value langtype** | 一个具体 XValue 的 head langtype(见 [[langtype语义类型]]) | **实例**:描述这个值**是什么** | 具体固定——单一种类 + 确定 `[dims]`(每维具体整数),不含并集与任何轴量词 | -def langtype 是「值域」,value langtype 是值域里「一个点」;类型检查即判定后者是否落进前者(匹配语义见 [[匹配语义与变参]])。 +def langtype 是「值域」,value langtype 是值域里「一个点」;类型检查即判定后者是否落进前者(匹配语义 +见 [[匹配语义与变参]])。 ## kindexpr(简写) -一段**具体的 langtype 串**——无论是某个 value 的 langtype,还是某条 def 签名里某参数的 langtype——统称 **kindexpr**。故 kindexpr 与 langtype 指同一文法产物:`langtype` 强调 head 的语义类型维,`kindexpr` 强调「一条具体的类型表达式串」。def langtype 是允许模式构造(并集 `|` 与轴量词 `.`/`?`/`*`/`+`)的 kindexpr,value langtype 是不含模式构造的 kindexpr。下文与各卷凡书「kindexpr」即指一条具体 langtype 串。 +一段**具体的 langtype 串**——无论是某个 value 的 langtype,还是某条 def 签名里某参数的 langtype——统称 +**kindexpr**。故 kindexpr 与 langtype 指同一文法产物:`langtype` 强调 head 的语义类型维,`kindexpr` +强调「一条具体的类型表达式串」。def langtype 是允许模式构造(并集 `|` 与轴量词 `.`/`?`/`*`/`+`)的 +kindexpr,value langtype 是不含模式构造的 kindexpr。下文与各卷凡书「kindexpr」即指一条具体 langtype +串。 ## 两条 runtime-c ABI(供外部调用) -runtime-c 对外开放两组 langtype 能力,一一对应两型(`kvlang_myrwir.h` 与正典 codec,见 [[cruntime与后端abi]]),供扩展运行时与嵌入方调用: +runtime-c 对外开放两组 langtype 能力,一一对应两型(`kvlang_myrwir.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 kindexpr 合法、`LangtypeMatch` 把一个值的 + `(kind,ndim,dims)` 对一条 def kindexpr 作**逐值无状态**模式匹配。用于签名校验与派发(参数变参判定 + 不在此,靠主槽 `dynamic` 字节,见 [[函数]])。 +- **具体侧(value langtype)**:把一条具体 kindexpr 解析/解码为 `(kind, ndim, dims, 元素字节宽)`——唯 + 一事实源为正典 codec `kvspaceDecodeHead`(读 head 的 value langtype)与 layout 的 + `kvlangLangtypeParse`(见 [[layout流水线接口]])。用于零拷贝定位、显示、round-trip。 -两 ABI 同源同文法(都吃一条 kindexpr 串),差别只在角色:**模式匹配** vs **具体解析**。runtime-c **不得**为二者各造一份编解码——文法与 codec 只此一处。 +两 ABI 同源同文法(都吃一条 kindexpr 串),差别只在角色:**模式匹配** vs **具体解析**。runtime-c ** +不得**为二者各造一份编解码——文法与 codec 只此一处。 ## 锚例 -- 标量并集、多维形状、动态维、字符串标注:`tutorial/10-types/`(`01-typed-map.kv`~`05-tuple-key.kv`)。 -- 嵌套 mapexpr 与元组键落入 kvspace round-trip:`tutorial/10-types/04-nested-type.kv`、`05-tuple-key.kv`。 +- 标量并集、多维形状、动态维、字符串标注:`tutorial/10-types/`(`01-typed-map.kv`~ + `05-tuple-key.kv`)。 +- 嵌套 mapexpr 与元组键落入 kvspace round-trip:`tutorial/10-types/04-nested-type.kv`、 + `05-tuple-key.kv`。 - 变参 `...`:`print`/`println`/`min`/`max` 全 tutorial 广泛使用。 "#### -> /lib/kvlang/spec/类型系统/langtype签名类型表达式 } 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 e04dd8c..6fc243a 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,15 +8,24 @@ lib kvlang/spec/类型系统/归属与存储 { | def rwir 路由头 | `/lib/` | `def rwir` | | native 算子签名 | C 注册表(不落入 kvspace) | —— | -**铁律**:`rwfunc` 每个参数落入 kvspace 的 langtype 与源码里的类型标注**逐字节相同**(同一文法,含 `...`);`def rwir` 源码不声明,其参数 langtype 由各 runtime 注册时按同一文法写入。签名**不写进 langtype 串**,也不塞进主槽 body,分两处存(详见 [[总体方案]]「签名不入 langtype 串」): +**铁律**:`rwfunc` 每个参数落入 kvspace 的 langtype 与源码里的类型标注**逐字节相同**(同一文法,含 +`...`);`def rwir` 源码不声明,其参数 langtype 由各 runtime 注册时按同一文法写入。签名**不写进 +langtype 串**,也不塞进主槽 body,分两处存(详见 [[总体方案]]「签名不入 langtype 串」): -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. **主槽计数头**:主槽(如 `/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 串。 -故 rwfunc/def rwir 主槽的 langtype 就是裸种类名 `rwfunc`/`def rwir` 本身,不再是「签名 langtype 串」。native 算子的 langtype 内联在 C 注册表中,是唯一权威来源,运行时匹配**直接读 C 表、不回查 kvspace**;数值多类型算子在 C 表中融合为单条(如 `add(a:int8|…|float64, b:…)`)。 +故 rwfunc/def rwir 主槽的 langtype 就是裸种类名 `rwfunc`/`def rwir` 本身,不再是「签名 langtype +串」。native 算子的 langtype 内联在 C 注册表中,是唯一权威来源,运行时匹配**直接读 C 表、不回查 +kvspace**;数值多类型算子在 C 表中融合为单条(如 `add(a:int8|…|float64, b:…)`)。 ## 强制类型标注 -`rwfunc` 签名中每个参数与每个返回值**必须**声明类型(`name:type_expr`)。缺标注的签名**拒绝装载**——layout 在语法检查期报错,指出该参数/返回值无类型标注。类型标注须通过 langtype 合法性校验(拒绝非种类名,见下)。`def rwir` 路由头由 runtime 注册(源码不声明),其参数类型在注册接口处按同一合法性规则校验。 +`rwfunc` 签名中每个参数与每个返回值**必须**声明类型(`name:type_expr`)。缺标注的签名**拒绝装载 +**——layout 在语法检查期报错,指出该参数/返回值无类型标注。类型标注须通过 langtype 合法性校验(拒绝非 +种类名,见下)。`def rwir` 路由头由 runtime 注册(源码不声明),其参数类型在注册接口处按同一合法性规 +则校验。 "#### -> /lib/kvlang/spec/类型系统/归属与存储 } 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 0fd877e..32e58d1 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" @@ -7,7 +7,8 @@ lib kvlang/spec/类型系统/文法与合法性 { - **并集** `A|B`——以 `|` 拆分为若干 atom,表「A 或 B」。多态**必须**用显式并集表达。 - **atom** = 形状(shape)或 map 表达式(mapexpr)。 - **shape** = 可选维度 `dims` 后跟 `any` 或精确种类名。 -- **dims** = `[]` 或 `[elem,elem,…]`;每个 `elem` 是一个**轴量词**,逗号分隔(借鉴正则,一个 dims 就是一段「轴序列」的模式): +- **dims** = `[]` 或 `[elem,elem,…]`;每个 `elem` 是一个**轴量词**,逗号分隔(借鉴正则,一个 dims 就 + 是一段「轴序列」的模式): | `elem` | 匹配的轴数 | 每轴长度 | 正则类比 | |--------|-----------|---------|---------| @@ -17,15 +18,22 @@ lib kvlang/spec/类型系统/文法与合法性 { | `*` | 0+ | 任意 | `.*` | | `+` | 1+ | 任意 | `.+` | - 空 `[]` **等价** `[.]`(恰一维、任意长)——字符串标注 `[]char/<编码>` 即此形。一个 dims 内**至多一个**变元量词(`?`/`*`/`+`),其余须为定长元(整数或 `.`)——保证匹配 O(n) 确定、无回溯(见 [[匹配语义与变参]])。 + 空 `[]` **等价** `[.]`(恰一维、任意长)——字符串标注 `[]char/<编码>` 即此形。一个 dims 内**至多一 + 个**变元量词(`?`/`*`/`+`),其余须为定长元(整数或 `.`)——保证匹配 O(n) 确定、无回溯(见 [[匹配语 + 义与变参]])。 - **mapexpr** = `key·value`,`value` 递归为完整类型表达式(故 map 可无限嵌套)。 -- **key** = `[]char/<编码>`(字符串键)或 `[scalar,…]`(标量元组键);`scalar` 限 `bool` 与十个定宽数字种类。 +- **key** = `[]char/<编码>`(字符串键)或 `[scalar,…]`(标量元组键);`scalar` 限 `bool` 与十个定宽 + 数字种类。 - **any** = 通配,匹配任意种类;是**唯一**简写。 -- **structref** = 以 `/` 起始的原型路径(如 `/lib/Point`),作为 atom 标注结构类型(见 [[容器]] 的 struct)。 +- **structref** = 以 `/` 起始的原型路径(如 `/lib/Point`),作为 atom 标注结构类型(见 [[容器]] 的 + struct)。 -> 轴量词 `.`/`?`/`*`/`+` 与正则一致,**只描述单个值的形状**。而**参数变参**(一个参数位吸收 0..N 个实参,旧写法末读参尾缀 `...`)是**签名**层的 arity 构造,**不属于类型表达式**,见 [[函数]];它落成函数主槽的 `dynamic` 字节,参数 langtype 子槽保持纯净(不含 `...`)。 +> 轴量词 `.`/`?`/`*`/`+` 与正则一致,**只描述单个值的形状**。而**参数变参**(一个参数位吸收 0..N 个 + 实参,旧写法末读参尾缀 `...`)是**签名**层的 arity 构造,**不属于类型表达式**,见 [[函数]];它落成 + 函数主槽的 `dynamic` 字节,参数 langtype 子槽保持纯净(不含 `...`)。 -**合法性校验**(layout 与 runtime 一致):每个 atom 的基须为 `known` 种类名或 `any`;键须为 `[]char/<编码>` 或全标量元组。非法示例及拒因: +**合法性校验**(layout 与 runtime 一致):每个 atom 的基须为 `known` 种类名或 `any`;键须为 +`[]char/<编码>` 或全标量元组。非法示例及拒因: | 非法 | 拒因 | |------|------| @@ -38,8 +46,10 @@ lib kvlang/spec/类型系统/文法与合法性 { | 裸 `[]` / 裸 `[.]` | 无基种类 | | `[*,+]int64`、`[?,*]int64` | 一个 dims 含多于一个变元量词(`?`/`*`/`+`) | -源码类型标注最前的 `*`/`@` 前缀(如 `*int64`、`@[256,256]uint8`)**合法**,layout 解析时剥离前缀落成 head `ref` 字节,再校验剩余 langtype;wire 层 langtype 串不含前缀(见 [[总体方案]])。 +源码类型标注最前的 `*`/`@` 前缀(如 `*int64`、`@[256,256]uint8`)**合法**,layout 解析时剥离前缀落成 +head `ref` 字节,再校验剩余 langtype;wire 层 langtype 串不含前缀(见 [[总体方案]])。 -`def rwir` 是路由头 langtype(仅落于 `/lib/`),**不得**作为类型标注书写;`rwfunc` 有 kvlang 实现体,可被任意 main-runtime 直接解释,**无需也没有** def rwfunc(见 [[种类与定宽类型]])。 +`def rwir` 是路由头 langtype(仅落于 `/lib/`),**不得**作为类型标注书写;`rwfunc` 有 kvlang 实 +现体,可被任意 main-runtime 直接解释,**无需也没有** def rwfunc(见 [[种类与定宽类型]])。 "#### -> /lib/kvlang/spec/类型系统/文法与合法性 } 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 d4aeb94..d239816 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,18 +2,24 @@ lib kvlang/spec/类型系统/匹配语义与变参 { r####"# 匹配语义与变参 -本章匹配语义作用于 **def langtype**(模式):把一个值的 value langtype `(kind,ndim,dims)` 与签名里的 def langtype 判定是否命中(两型见 [[langtype签名类型表达式]])。匹配**恒逐值、无状态**:只看单个值,不在参数间携带任何环境(跨操作数的维相等/输出推断不在类型层,归 op 的 shape function,见 [[函数调用与内建]])。 +本章匹配语义作用于 **def langtype**(模式):把一个值的 value langtype `(kind,ndim,dims)` 与签名里的 +def langtype 判定是否命中(两型见 [[langtype签名类型表达式]])。匹配**恒逐值、无状态**:只看单个值, +不在参数间携带任何环境(跨操作数的维相等/输出推断不在类型层,归 op 的 shape function,见 [[runtimec内 +建]])。 ## 匹配语义 -一个值(种类 `k`、维数 `n`、维列表 `d`)匹配类型表达式 `E`:按 `|` 拆成若干 atom,**任一** atom 命中即匹配。单个 atom 的判定: +一个值(种类 `k`、维数 `n`、维列表 `d`)匹配类型表达式 `E`:按 `|` 拆成若干 atom,**任一** atom 命中 +即匹配。单个 atom 的判定: 1. atom 为 `any` → 命中。 -2. atom 含 `·`(mapexpr)→ 命中当且仅当 `k == stringkeymap`。键/值结构在**匹配期不再校验**(已在装载期校验合法性)。 +2. atom 含 `·`(mapexpr)→ 命中当且仅当 `k == stringkeymap`。键/值结构在**匹配期不再校验**(已在装载 + 期校验合法性)。 3. atom 有 `[` 前缀(shape)→ 先按维度段做形状匹配,再以剩余基种类匹配 `k`。 4. atom 无 `[` 前缀(标量)→ 命中当且仅当 `n == 0` 且基种类等于 `k`(`any` 除外走精确字符串相等)。 -**形状匹配**(维度段的轴量词序列 → `n`,`d`,轴量词见 [[文法与合法性]])。一个 dims 至多一个变元量词(`?`/`*`/`+`),故切分唯一、无回溯:设定长元(整数或 `.`)共 `f` 个,令 `rem = n - f`: +**形状匹配**(维度段的轴量词序列 → `n`,`d`,轴量词见 [[文法与合法性]])。一个 dims 至多一个变元量词 +(`?`/`*`/`+`),故切分唯一、无回溯:设定长元(整数或 `.`)共 `f` 个,令 `rem = n - f`: | 维度段 | 命中条件 | |--------|---------| @@ -22,24 +28,32 @@ lib kvlang/spec/类型系统/匹配语义与变参 { | 含一个 `*` | `rem ≥ 0`;`*` 吸收 `rem` 个轴,其余定长元按位逐轴判定 | | 含一个 `+` | `rem ≥ 1`;`+` 吸收 `rem` 个轴,其余定长元按位逐轴判定 | -空 `[]` **等价** `[.]`——「恰一维、任意长」。字符串标注 `[]char/<编码>` 即一维字符序列。例:`[.]`↔恰 1 维;`[.,.]`↔恰 2 维;`[*]`↔任意秩;`[*,.]`↔秩≥1、末维任意;`[512,*]`↔首维 512、秩≥1。 +空 `[]` **等价** `[.]`——「恰一维、任意长」。字符串标注 `[]char/<编码>` 即一维字符序列。例:`[.]`↔恰 +1 维;`[.,.]`↔恰 2 维;`[*]`↔任意秩;`[*,.]`↔秩≥1、末维任意;`[512,*]`↔首维 512、秩≥1。 任一失配即 TypeError:装载期由 layout 报诊断,运行期写 vthread 错误并停机。 ## 参数变参(签名层,非类型) -一个**参数位**吸收 0..N 个同型实参(`print`/`println`/`min`/`max` 等 arity 开放算子)是**签名**的 arity 属性,**不属于类型表达式**——源码在末读参尾缀 `...` 声明,由签名解析器剥离,落成函数主槽的 `dynamic` 字节,该参数 langtype 子槽保持纯净(见 [[函数]]、[[指令布局格式]])。派发时:主槽 `dynamic=1` → 末读参对**每个**尾随实参按其(纯净)langtype 逐个判定。`LangtypeValid`/`LangtypeMatch` 永不见 `...`。 +一个**参数位**吸收 0..N 个同型实参(`print`/`println`/`min`/`max` 等 arity 开放算子)是**签名**的 +arity 属性,**不属于类型表达式**——源码在末读参尾缀 `...` 声明,由签名解析器剥离,落成函数主槽的 +`dynamic` 字节,该参数 langtype 子槽保持纯净(见 [[函数]]、[[指令布局格式]])。派发时:主槽 +`dynamic=1` → 末读参对**每个**尾随实参按其(纯净)langtype 逐个判定。`LangtypeValid`/`LangtypeMatch` +永不见 `...`。 XValue head 三正交维编码见 [[总体方案]](本卷只界定 langtype 串的文法与匹配语义)。 ## 多态派发 - **native 算子**(如 `+`)内建多态,签名只做类型检查;分派在 C 算子内部按实参种类完成。 -- **rwir 指令**(如 `numpy·add`)经 def rwir 路由到有对应 myrwircaps 的 runtime,按实参实际种类分派;高维形状由该 runtime 自行处理。 +- **rwir 指令**(如 `numpy·add`)经 def rwir 路由到有对应 myrwircaps 的 runtime,按实参实际种类分 + 派;高维形状由该 runtime 自行处理。 - **用户函数**(rwfunc)以并集声明接受集,函数体内用种类分支处理各分支。 ## 语法冲突规避 -签名以 `,` 分隔参数,形状维度段内也用 `,` 分隔维。签名解析器**跟踪方括号深度**:见 `[` 进形状态、见 `]` 退出;形状态内的 `,` 归维、态外的 `,` 归参数。类型表达式内不出现 `(` `)` `:` `->` 空格,故与签名外层结构无歧义。 +签名以 `,` 分隔参数,形状维度段内也用 `,` 分隔维。签名解析器**跟踪方括号深度**:见 `[` 进形状态、见 +`]` 退出;形状态内的 `,` 归维、态外的 `,` 归参数。类型表达式内不出现 `(` `)` `:` `->` 空格,故与签名 +外层结构无歧义。 "#### -> /lib/kvlang/spec/类型系统/匹配语义与变参 } 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 d171447..ca8db7f 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" @@ -2,7 +2,9 @@ lib kvlang/spec/类型系统/数组形态 { r####"# 数组形态 -kvlang 的数组有**两种物理形态**:**compact**(稠密:全量元素连续打包进单个 XValue)与 **stringkeymap**(稀疏:散 key,每元素独立落库,未 set 的 key 不存在)。两形态由字面量括号选定,访问算子不同,但都被 `ndarray·*` 元数据算子统一观测。 +kvlang 的数组有**两种物理形态**:**compact**(稠密:全量元素连续打包进单个 XValue)与 +**stringkeymap**(稀疏:散 key,每元素独立落库,未 set 的 key 不存在)。两形态由字面量括号选定,访问 +算子不同,但都被 `ndarray·*` 元数据算子统一观测。 ## 锚例 @@ -23,20 +25,24 @@ kvlang 的数组有**两种物理形态**:**compact**(稠密:全量元素 | `[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 对齐字符串数组) | 变长/可增长;字符串数组等变长集合用此形式 | -- compact 字面量降级为 `array(…)` 构造。变长字符串元素进 compact `[…]` 在 layout 语法检查期报错(`compact array [...] cannot hold variable-length string element`)。 +- compact 字面量降级为 `array(…)` 构造。变长字符串元素进 compact `[…]` 在 layout 语法检查期报错 + (`compact array [...] cannot hold variable-length string element`)。 - stringkeymap 字面量降级为 `map(…)` 构造,只作赋值右值或 `for-in` 源。 ## 定长初始化(无需逐元素赋值) -大数组不可能逐个 `a[i] = v` 赋值。写目标声明**定长维度**(`[N]T` / `[d0,d1]T`,方括号内全为正整数)时,两种简写把整块 compact 一次成型: +大数组不可能逐个 `a[i] = v` 赋值。写目标声明**定长维度**(`[N]T` / `[d0,d1]T`,方括号内全为正整数) +时,两种简写把整块 compact 一次成型: | 字面量 | 语义 | |--------|------| | `a:[1024]int32 = []` | 空初始化:按声明维度分配,全零 | | `b:[256,256]float32 = [1...]` | 填充初始化:按声明维度分配,每元素填 `1`(填充值按元素种类编码,`1`→`float32 1.0`) | -- 两者降级为 `array·fill(langtype[, v])`:`langtype` 即写类型(维度来源),`v` 为填充值(`[]` 省略即全零)。runtime 一条指令批量填充,不展开成 N 个字面量参数。 -- `[v...]` 只允许**单一**填充值,且写类型必须是定长数组(`[]T` 动态一维、`[.,N]T` 含任意长维均报错)。(此处 `[v...]` 是**值字面量**的填充展开,与类型表达式无关。) +- 两者降级为 `array·fill(langtype[, v])`:`langtype` 即写类型(维度来源),`v` 为填充值(`[]` 省略即 + 全零)。runtime 一条指令批量填充,不展开成 N 个字面量参数。 +- `[v...]` 只允许**单一**填充值,且写类型必须是定长数组(`[]T` 动态一维、`[.,N]T` 含任意长维均报 + 错)。(此处 `[v...]` 是**值字面量**的填充展开,与类型表达式无关。) - 动态一维 `a:[]int32 = []` 仍是**空数组**(0 长度),不触发填充。 "#### -> /lib/kvlang/spec/类型系统/数组形态 } diff --git "a/stdlib/kvlang/spec/03-\347\261\273\345\236\213\347\263\273\347\273\237/10-compact\345\275\242\346\200\201.kv" "b/stdlib/kvlang/spec/03-\347\261\273\345\236\213\347\263\273\347\273\237/10-compact\345\275\242\346\200\201.kv" index 347a662..ad89735 100644 --- "a/stdlib/kvlang/spec/03-\347\261\273\345\236\213\347\263\273\347\273\237/10-compact\345\275\242\346\200\201.kv" +++ "b/stdlib/kvlang/spec/03-\347\261\273\345\236\213\347\263\273\347\273\237/10-compact\345\275\242\346\200\201.kv" @@ -2,14 +2,17 @@ lib kvlang/spec/类型系统/compact形态 { r####"# compact 形态 -compact 数组是**单个 XValue**:head 的 langtype(langtype)形如 `[4]int64`(含维度+元素种类),storetype=ARRAYND,body 是连续的定宽元素字节。 +compact 数组是**单个 XValue**:head 的 langtype(langtype)形如 `[4]int64`(含维度+元素种类), +storetype=ARRAYND,body 是连续的定宽元素字节。 ```kv a:[]int64 = [10, 20, 30, 40] // head langtype = [4]int64,body = 4×8 字节 ``` -- head 的 langtype = langtype 串形如 `[4]int64`(元素种类为 `int64`,**非** `array`);storetype=ARRAYND(见 `tutorial/04-ndarray/xv_meta.kv`)。 -- 字符串是 compact 的字符序列:`s:char/utf8 = "hi"` 的 langtype 为 `[2]char/utf8`。单个字符串是 compact;**字符串的数组**是变长集合,必须 stringkeymap。 +- head 的 langtype = langtype 串形如 `[4]int64`(元素种类为 `int64`,**非** `array`); + storetype=ARRAYND(见 `tutorial/04-ndarray/xv_meta.kv`)。 +- 字符串是 compact 的字符序列:`s:char/utf8 = "hi"` 的 langtype 为 `[2]char/utf8`。单个字符串是 + compact;**字符串的数组**是变长集合,必须 stringkeymap。 ### compact 元素访问 @@ -21,7 +24,8 @@ a[2] = 99 // 等价 xv·set(a, 2, 99) -> a 99 -> a[0] // 右箭头下标写,等价 xv·set(a, 0, 99) -> a ``` -`xv·at` / `xv·set` **仅接受 compact 数组**(维数非 0):对 stringkeymap 或标量报 TypeError。索引个数**必须**等于维数,按 row-major 折算扁平偏移;越界报 IndexError。写回保持 dims 不变。 +`xv·at` / `xv·set` **仅接受 compact 数组**(维数非 0):对 stringkeymap 或标量报 TypeError。索引个数 +**必须**等于维数,按 row-major 折算扁平偏移;越界报 IndexError。写回保持 dims 不变。 ### 多维 compact(tensor) 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 a97cd63..16bac8e 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" @@ -2,7 +2,9 @@ lib kvlang/spec/类型系统/stringkeymap形态 { r####"# stringkeymap 形态 -stringkeymap 数组的**容器值**是一个 storetype=index 的 XValue(langtype 为 map langtype,如 `[]char/utf8·int64`;body 空,成员名索引落 `base·` memindex,dims=[len,cap,M]),**每个元素**是独立子 key `base·i`: +stringkeymap 数组的**容器值**是一个 storetype=index 的 XValue(langtype 为 map langtype,如 +`[]char/utf8·int64`;body 空,成员名索引落 `base·` memindex,dims=[len,cap,M]),**每个元素**是独立 +子 key `base·i`: ```kv nums = {10, 20, 30, 40} // 每元素落 nums·0 … nums·3 @@ -10,7 +12,9 @@ for (x in nums) { … } // 遍历散 key 元素 names = {"apple", "banana", "cherry"} // 变长字符串数组必须 stringkeymap ``` -散 key 元素以坐标段 `base·[i]` 访问(经 `kv·get`),或以 `for-in` / `kv·listlen` / `kv·listn` 遍历。坐标段支持多值键(含小数):`geo·[39.9,116.4] = "Beijing"`,物理以字符串格式落 key(见 `tutorial/04-ndarray/geo_coord.kv`)。 +散 key 元素以坐标段 `base·[i]` 访问(经 `kv·get`),或以 `for-in` / `kv·listlen` / `kv·listn` 遍历。 +坐标段支持多值键(含小数):`geo·[39.9,116.4] = "Beijing"`,物理以字符串格式落 key(见 +`tutorial/04-ndarray/geo_coord.kv`)。 ## 两形态互转 @@ -19,6 +23,7 @@ names = {"apple", "banana", "cherry"} // 变长字符串数组必须 stringkey | `array·scatter(a)` | compact → stringkeymap(散 key) | | `array·compact(b)` | stringkeymap → compact | -字面量初始化默认按括号定形态;`scatter`/`compact` 显式转换(见 `tutorial/04-ndarray/separated.kv`)。 +字面量初始化默认按括号定形态;`scatter`/`compact` 显式转换(见 +`tutorial/04-ndarray/separated.kv`)。 "#### -> /lib/kvlang/spec/类型系统/stringkeymap形态 } diff --git "a/stdlib/kvlang/spec/03-\347\261\273\345\236\213\347\263\273\347\273\237/12-\347\250\240\345\257\206vs\347\250\200\347\226\217.kv" "b/stdlib/kvlang/spec/03-\347\261\273\345\236\213\347\263\273\347\273\237/12-\347\250\240\345\257\206vs\347\250\200\347\226\217.kv" index 68a5e48..64a0a21 100644 --- "a/stdlib/kvlang/spec/03-\347\261\273\345\236\213\347\263\273\347\273\237/12-\347\250\240\345\257\206vs\347\250\200\347\226\217.kv" +++ "b/stdlib/kvlang/spec/03-\347\261\273\345\236\213\347\263\273\347\273\237/12-\347\250\240\345\257\206vs\347\250\200\347\226\217.kv" @@ -20,6 +20,7 @@ sparse:[int32,int32]·int32 = {} // 稀疏,storetype=index sparse·[0,0] -> x // 未写坐标 → None(子 key 不存在) ``` -两种落库共享 `ndarray·*` 观测(`numel` 对稀疏形态返回**实存成员数**,非坐标空间容量),并经下节 `array·scatter`/`array·compact` 互转。 +两种落库共享 `ndarray·*` 观测(`numel` 对稀疏形态返回**实存成员数**,非坐标空间容量),并经下节 +`array·scatter`/`array·compact` 互转。 "#### -> /lib/kvlang/spec/类型系统/稠密vs稀疏 } diff --git "a/stdlib/kvlang/spec/03-\347\261\273\345\236\213\347\263\273\347\273\237/14-\345\256\271\345\231\250.kv" "b/stdlib/kvlang/spec/03-\347\261\273\345\236\213\347\263\273\347\273\237/14-\345\256\271\345\231\250.kv" index 8ae093a..4fd5eb8 100644 --- "a/stdlib/kvlang/spec/03-\347\261\273\345\236\213\347\263\273\347\273\237/14-\345\256\271\345\231\250.kv" +++ "b/stdlib/kvlang/spec/03-\347\261\273\345\236\213\347\263\273\347\273\237/14-\345\256\271\345\231\250.kv" @@ -2,29 +2,40 @@ lib kvlang/spec/类型系统/容器 { r####"# 容器 -kvlang 的复合命名数据只有两种容器语义类型:**stringkeymap**(键-值映射)与 **struct**(异构命名成员)。kvlang **没有** `dict` 种类,也没有 `object` 或 `scope` 种类(见 [[总体方案]])。容器物理落 storetype=index,成员经 `{key}·` memindex 兄弟槽枚举(与 lib/rwfunc 目录节点用 `/` 子路径不同)。此外 **ptr**(软链接)是 ref=1 的值形态,指向另一 key。 +kvlang 的复合命名数据只有两种容器语义类型:**stringkeymap**(键-值映射)与 **struct**(异构命名成 +员)。kvlang **没有** `dict` 种类,也没有 `object` 或 `scope` 种类(见 [[总体方案]])。容器物理落 +storetype=index,成员经 `{key}·` memindex 兄弟槽枚举(与 lib/rwfunc 目录节点用 `/` 子路径不同)。此 +外 **ptr**(软链接)是 ref=1 的值形态,指向另一 key。 ## 锚例 - stringkeymap 字面量与访问:`tutorial/10-types/01-typed-map.kv`、`tutorial/05-dict/literal.kv`。 -- stringkeymap 与动态键、缺失返 None:`tutorial/10-types/02-string-map.kv`、`05-dict/kv_has_string_key.kv`。 +- stringkeymap 与动态键、缺失返 None:`tutorial/10-types/02-string-map.kv`、 + `05-dict/kv_has_string_key.kv`。 - 嵌套 map 与元组键签名:`tutorial/10-types/04-nested-type.kv`、`05-tuple-key.kv`。 - struct 声明/实例化/默认值/多类型字段:`tutorial/12-struct/00-point.kv`、`01-fields.kv`。 - 指针解引用、局部结构体、链表/树/图:`tutorial/12-struct/03-linked-list.kv`~`07-list-local.kv`。 ## 容器结构 -容器在 kvspace 中分两部分落库,`·`(U+00B7 中点)是值容器唯一的 memindex 标记(注:`/lib/{pkg}·{func}` 中的 `·` 是包·函数命名分隔符,与 memindex 无关,详见 [[总体方案]]): +容器在 kvspace 中分两部分落库,`·`(U+00B7 中点)是值容器唯一的 memindex 标记(注: +`/lib/{pkg}·{func}` 中的 `·` 是包·函数命名分隔符,与 memindex 无关,详见 [[总体方案]]): -- **容器值**:落在裸 base 键,storetype=index,body 空;langtype 为 map langtype(如 `[]char/utf8·int64`)或 struct 原型路径(如 `/lib/Point`)。 +- **容器值**:落在裸 base 键,storetype=index,body 空;langtype 为 map langtype(如 + `[]char/utf8·int64`)或 struct 原型路径(如 `/lib/Point`)。 - **成员**:`base·name` 是独立子 key,各自持成员值。 -- **memindex**:落在 `base·` 键(尾中点),storetype=index,其 body 是成员名索引矩阵,是成员枚举的权威来源。 +- **memindex**:落在 `base·` 键(尾中点),storetype=index,其 body 是成员名索引矩阵,是成员枚举的权 + 威来源。 -memindex 的线格式为 dims = `[len, cap, M]` 的矩阵:`len` = 有效成员数、`cap` = 预留行数(`cap ≥ len`,满则翻倍扩容)、`M` = 成员名 UTF-8 字节最大长向上 8 对齐后的**行宽**;body 为 `cap × M` 字节,前 `len` 行是有序成员名(NUL 补齐),其余行全 NUL。容量内增删成员 body 长恒定、就地覆写。`M` 是行宽(行 stride),`cap` 是可翻倍的容量。 +memindex 的线格式为 dims = `[len, cap, M]` 的矩阵:`len` = 有效成员数、`cap` = 预留行数 +(`cap ≥ len`,满则翻倍扩容)、`M` = 成员名 UTF-8 字节最大长向上 8 对齐后的**行宽**;body 为 +`cap × M` 字节,前 `len` 行是有序成员名(NUL 补齐),其余行全 NUL。容量内增删成员 body 长恒定、就地 +覆写。`M` 是行宽(行 stride),`cap` 是可翻倍的容量。 ## stringkeymap -**stringkeymap** 是一等 map 类型,langtype 为 `key·value`(见 [[langtype签名类型表达式]]):`[]char/utf8·int64` 即 `map[string]int64`,value 可递归嵌套(`[]char/utf8·[]char/utf8·int64`)。 +**stringkeymap** 是一等 map 类型,langtype 为 `key·value`(见 [[langtype签名类型表达式]]): +`[]char/utf8·int64` 即 `map[string]int64`,value 可递归嵌套(`[]char/utf8·[]char/utf8·int64`)。 ```kv m:[]char/utf8·int64 = {} // 空 map 同样须带类型标注 @@ -35,6 +46,7 @@ kv·get(m, "a") -> x // 动态键读;缺失返回 None ## 空容器字面量须带类型标注 -`{}` 空 stringkeymap 字面量**必须**在赋值目标处带类型标注(如 `x:[]char/utf8·int64 = {}`);无标注时 layout 报错——空字面量本身无法推断 key/value 类型。 +`{}` 空 stringkeymap 字面量**必须**在赋值目标处带类型标注(如 `x:[]char/utf8·int64 = {}`);无标注时 +layout 报错——空字面量本身无法推断 key/value 类型。 "#### -> /lib/kvlang/spec/类型系统/容器 } diff --git "a/stdlib/kvlang/spec/03-\347\261\273\345\236\213\347\263\273\347\273\237/15-\346\210\220\345\221\230\350\256\277\351\227\256.kv" "b/stdlib/kvlang/spec/03-\347\261\273\345\236\213\347\263\273\347\273\237/15-\346\210\220\345\221\230\350\256\277\351\227\256.kv" index 236fb71..8c288d5 100644 --- "a/stdlib/kvlang/spec/03-\347\261\273\345\236\213\347\263\273\347\273\237/15-\346\210\220\345\221\230\350\256\277\351\227\256.kv" +++ "b/stdlib/kvlang/spec/03-\347\261\273\345\236\213\347\263\273\347\273\237/15-\346\210\220\345\221\230\350\256\277\351\227\256.kv" @@ -8,14 +8,17 @@ lib kvlang/spec/类型系统/成员访问 { | `base·*k` | 动态键:变量 `k` 的值作成员名(用于局部容器) | | `kv·get(base, k)` / `kv·set(base, k, v)` | 动态字符串键读/写 | -容器成员一律走 `·`(或 `kv·get`/`kv·set`),**不得**用 `[]`;`[]` 只索引 compact 数组(见 [[数组形态]])。 +容器成员一律走 `·`(或 `kv·get`/`kv·set`),**不得**用 `[]`;`[]` 只索引 compact 数组(见 [[数组形 +态]])。 ### `base·name` 的 base 解析:按值优先、按名回退 `base·name`(读写同规则)中 base 的解析: -1. **按值解引用**:base 持有非空字符串值(路径指针)→ 成员键 = `值(base)·name`。如 `"/n1" -> p` 后 `p·next` 解析为 `/n1·next`。 -2. **按名回退**:base 无值(或非字符串)→ 成员键 = `解析(base)·name`;解析帧感知:裸名 → `帧根/base`,`/` 开头 → 直通。 +1. **按值解引用**:base 持有非空字符串值(路径指针)→ 成员键 = `值(base)·name`。如 `"/n1" -> p` 后 + `p·next` 解析为 `/n1·next`。 +2. **按名回退**:base 无值(或非字符串)→ 成员键 = `解析(base)·name`;解析帧感知:裸名 → + `帧根/base`,`/` 开头 → 直通。 该规则让「局部结构体」(base 无值,按名)与「指针解引用」(base 存路径字符串,按值)共用一套语法。 "#### -> /lib/kvlang/spec/类型系统/成员访问 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 7550fa1..493f806 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" @@ -2,7 +2,10 @@ lib kvlang/spec/类型系统/ptr { r####"# ptr(软链接) -**ptr** 不是种类,而是 head 的 `ref=1`(存储位置维):ptr 值的 head storetype/langtype 描述**目标的完整形态**,body 存**目标 key 路径**。源码类型标注最前可写 `*` 前缀(如 `*int64`)表 ref,layout 剥离后落成 head `ref` 独立字节;wire 层 langtype 串不含前缀(见 [[总体方案]]);赋值(Set)时据 head 的 storetype/langtype 做单跳类型检查。 +**ptr** 不是种类,而是 head 的 `ref=1`(存储位置维):ptr 值的 head storetype/langtype 描述**目标的 +完整形态**,body 存**目标 key 路径**。源码类型标注最前可写 `*` 前缀(如 `*int64`)表 ref,layout 剥 +离后落成 head `ref` 独立字节;wire 层 langtype 串不含前缀(见 [[总体方案]]);赋值(Set)时据 head +的 storetype/langtype 做单跳类型检查。 跨函数共享的数据放绝对路径,指针变量存其路径字符串: 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 08ea0e9..fe9e8f1 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" @@ -2,7 +2,8 @@ lib kvlang/spec/类型系统/struct { r####"# struct -`struct` 声明注册一个原型节点于 `/lib/`(storetype=index,langtype 为原型路径如 `/lib/Point`),字段带类型标注与默认值: +`struct` 声明注册一个原型节点于 `/lib/`(storetype=index,langtype 为原型路径如 +`/lib/Point`),字段带类型标注与默认值: ```kv struct Point { @@ -11,7 +12,9 @@ struct Point { } ``` -实例化 `Name{f=v}` 克隆原型子树、覆盖给定字段(其余取默认),并对每个字段做类型校验;实例是 struct 类型命名成员容器(storetype=index,成员在 `{key}·` memindex),成员经 `·` 访问。字段类型不符或写不存在的字段在 runtime 报 TypeError。 +实例化 `Name{f=v}` 克隆原型子树、覆盖给定字段(其余取默认),并对每个字段做类型校验;实例是 struct +类型命名成员容器(storetype=index,成员在 `{key}·` memindex),成员经 `·` 访问。字段类型不符或写不存 +在的字段在 runtime 报 TypeError。 ```kv p = Point{x=3.0 y=4.0} @@ -19,6 +22,8 @@ p·x -> a // 3.0 q = Point{} // 全取默认:0.0, 0.0 ``` -在签名中,结构类型以原型路径 `/lib/`(**structref** 类型表达式 atom)标注(见 [[langtype签名类型表达式]])。结构值可存进 map(int 键、struct 值)、以绝对路径指针连成链表/树/图(见 `tutorial/12-struct/`)。 +在签名中,结构类型以原型路径 `/lib/`(**structref** 类型表达式 atom)标注(见 [[langtype签名类 +型表达式]])。结构值可存进 map(int 键、struct 值)、以绝对路径指针连成链表/树/图(见 +`tutorial/12-struct/`)。 "#### -> /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 9e59d4d..caa80cc 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,14 +2,20 @@ lib kvlang/spec/类型系统/总体方案 { r####"# 类型系统总体方案:xvalue head 三正交维 -> **本卷为新方案,待敲定。** 敲定后据此重构 [[种类与定宽类型]]、[[langtype签名类型表达式]]、[[数组形态]]、[[容器]]。 +> **本卷为新方案,待敲定。** 敲定后据此重构 [[种类与定宽类型]]、[[langtype签名类型表达式]]、[[数组形 + 态]]、[[容器]]。 -每个 XValue 落入 kvspace 时,其类别由 head 三个**正交**字段表达,彻底取代旧的单一 `kind` 分类与 langtype 首字符 `*`/`@` 前缀。 +每个 XValue 落入 kvspace 时,其类别由 head 三个**正交**字段表达,彻底取代旧的单一 `kind` 分类与 +langtype 首字符 `*`/`@` 前缀。 - **`ref`(存储位置)** — 值放在哪:inline / 指针 / 扩展世界。1 字节。 - **`storetype`(物理布局,codec 视角)** — 字节怎么切。**闭合小集**,1 字节。 -- **`langtype`(语义类型,语言视角)** — 值是什么类型。**即旧的 langtype 串**,变长,保留高级语言的全部类型定义。 +- **`langtype`(语义类型,语言视角)** — 值是什么类型。**即旧的 langtype 串**,变长,保留高级语言的 + 全部类型定义。 -**核心分层**:codec([[XValueHead线格式]] 的编解码层)**只按 `storetype` 这 1 字节分派切字节**,完全不解析 `langtype` 串(对它只是一段透传字节);body 对 codec 恒为不透明字节。语言层(layout/runtime 类型系统)只读 `langtype` 串做类型检查、匹配、显示。这把 kvspace(寻址+内存空间,只认 storetype 1 字节)与 kvlang 类型系统(只认 langtype 串)彻底解耦。 +**核心分层**:codec([[XValueHead线格式]] 的编解码层)**只按 `storetype` 这 1 字节分派切字节**,完全 +不解析 `langtype` 串(对它只是一段透传字节);body 对 codec 恒为不透明字节。语言层(layout/runtime +类型系统)只读 `langtype` 串做类型检查、匹配、显示。这把 kvspace(寻址+内存空间,只认 storetype 1 字 +节)与 kvlang 类型系统(只认 langtype 串)彻底解耦。 "#### -> /lib/kvlang/spec/类型系统/总体方案 } diff --git "a/stdlib/kvlang/spec/03-\347\261\273\345\236\213\347\263\273\347\273\237/19-head\345\255\227\346\256\265.kv" "b/stdlib/kvlang/spec/03-\347\261\273\345\236\213\347\263\273\347\273\237/19-head\345\255\227\346\256\265.kv" index 8ef8e51..f3ad28b 100644 --- "a/stdlib/kvlang/spec/03-\347\261\273\345\236\213\347\263\273\347\273\237/19-head\345\255\227\346\256\265.kv" +++ "b/stdlib/kvlang/spec/03-\347\261\273\345\236\213\347\263\273\347\273\237/19-head\345\255\227\346\256\265.kv" @@ -13,6 +13,7 @@ lib kvlang/spec/类型系统/head字段 { | (storetype 物理字段) | 变 | 按 storetype 追加,见下表 | | `langtype` | 变长 | 类型表达式串,占至 `headlen`(长度 = `headlen` − 当前偏移,无需独立长度字段) | -`langtype` 恒为 head 最后一段(body 之前)。旧 1 字节 kindcode 方案作废——语义类型回归完整类型表达式串,方能承载 `[dims]`、map 的 `key·value`、struct 原型路径、def 族定义节点等高级定义。 +`langtype` 恒为 head 最后一段(body 之前)。旧 1 字节 kindcode 方案作废——语义类型回归完整类型表达式 +串,方能承载 `[dims]`、map 的 `key·value`、struct 原型路径、def 族定义节点等高级定义。 "#### -> /lib/kvlang/spec/类型系统/head字段 } 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 1aeb3de..dfcdbcd 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" @@ -10,10 +10,18 @@ lib kvlang/spec/类型系统/ref存储位置 { | 1 ptr | 目标 key 路径 | 软链接,单跳指向同型目标(head 的 storetype/langtype 即目标形态);`ptr → rwfunc` 即函数调用链 | | 2 @ext | 扩展句柄/定位符 | 单个值本体在扩展世界(fs 文件 / gpu tensordata),head 存元描述 | -**源码书写与 wire 的分工**:kvlang **源码**里,指针/扩展引用仍以 `*`/`@` 前缀写在类型**最前**(`*int64`、`@[256,256]uint8`,见 tutorial 例),这是源码类型标注文法的一部分。layout 解析源码时把该前缀**剥离**并落成 head 的 `ref` 独立字节;故 **wire 层 langtype 串不含 `*`/`@` 前缀**,存储位置一律经 `ref` 字节表达。`ref=2` 只表**单值**存于扩展世界,与目录类型 `index`/`extindex` 无关。 +**源码书写与 wire 的分工**:kvlang **源码**里,指针/扩展引用仍以 `*`/`@` 前缀写在类型**最前** +(`*int64`、`@[256,256]uint8`,见 tutorial 例),这是源码类型标注文法的一部分。layout 解析源码时把该 +前缀**剥离**并落成 head 的 `ref` 独立字节;故 **wire 层 langtype 串不含 `*`/`@` 前缀**,存储位置一律 +经 `ref` 字节表达。`ref=2` 只表**单值**存于扩展世界,与目录类型 `index`/`extindex` 无关。 ## 扩展世界句柄(ref=2 的 body 语义) -ref=2 时 body **不是**真实值字节,而是**逻辑定位串**(如 `/networld//proc//stdout`);langtype 仍为目标 langtype 串(不带 `@` 前缀),head 只存元描述。读取该 key 时 runtime 按 body 前缀**路由**到对应兑现器还原真实字节——如 `/lib/networld/*` 的 proc 兑现器把逻辑路径映射到 `/tmp/kvlangruntime-rs//` 物理文件读回。真实 xvalue 落在扩展世界(fs 文件、gpu tensordata),非 kvspace 元存;扩展算子的输出即以此形式写回其写槽。锚例:`tutorial/14-networld/05-capture.kv`。 +ref=2 时 body **不是**真实值字节,而是**逻辑定位串**(如 `/networld//proc//stdout`); +langtype 仍为目标 langtype 串(不带 `@` 前缀),head 只存元描述。读取该 key 时 runtime 按 body 前缀 +**路由**到对应兑现器还原真实字节——如 `/lib/networld/*` 的 proc 兑现器把逻辑路径映射到 +`/tmp/kvlangruntime-rs//` 物理文件读回。真实 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 3942115..cee20ab 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" @@ -12,7 +12,9 @@ lib kvlang/spec/类型系统/storetype物理布局 { | `index` | 成员名 **m×n 对齐字符串数组**,`dims=[len,cap,M]`(len=成员数、M=对齐宽度 align8、cap 保留容量) | 见下(目录节点主槽 body 记计数头或空) | stringkeymap、struct(值容器);lib、rwfunc、def 族(目录/定义节点) | | `extindex` | 同 index,`cap` 可增长(栈帧/运行栈扩容) | 同上 | rwfunc(vthread 运行栈等可扩展目录) | -数值 `dims` 供 codec O(1) 切字节,与 langtype 串内的 `[dims]` 语法一致(由 codec 保证同步)。index/extindex 的物理载体沿用今日敲定的 m×n 对齐字符串数组(每成员名 padding 至 M,`cap` 预留扩容),存成员/子项名。 +数值 `dims` 供 codec O(1) 切字节,与 langtype 串内的 `[dims]` 语法一致(由 codec 保证同步)。 +index/extindex 的物理载体沿用今日敲定的 m×n 对齐字符串数组(每成员名 padding 至 M,`cap` 预留扩 +容),存成员/子项名。 ### 成员如何枚举:`/` 目录 vs `·` memindex @@ -23,14 +25,19 @@ storetype=index/extindex 只表「这是有成员的索引节点」,成员的* | 目录节点 | lib、rwfunc、def rwir | **`/` 子路径**(kvspace 目录枚举) | `/lib/funca/[1,0]`、`/lib/funca/[1,1]` 为 `/lib/funca/` 的指令槽成员 | | 值容器 | stringkeymap、struct | **`{key}·` memindex 兄弟槽** | `p·` 存 `p` 的成员名索引 | -`{key}·` 中的 **memindex `·`** 是值容器(stringkeymap/struct)唯一的成员索引标记;rwfunc/lib/def 族是真目录,成员即 `/` 子路径,绝不用 memindex `·`。 +`{key}·` 中的 **memindex `·`** 是值容器(stringkeymap/struct)唯一的成员索引标记;rwfunc/lib/def 族 +是真目录,成员即 `/` 子路径,绝不用 memindex `·`。 **注意 `·` 的两种独立含义**——两者正交、勿混: -1. **memindex 标记**:值容器主槽 `{key}` 的兄弟槽 `{key}·`,存该容器的成员名索引。**仅** stringkeymap/struct 用。 -2. **包·函数命名分隔符**:`/lib/{pkg}·{func}`(如 `/lib/time·now`)中的 `·` 只是路径名里分隔包名与函数名的字符,是 rwfunc 所在**目录的名字的一部分**,与 memindex 无关。故 `/lib/time·now/` 仍是纯 `/` 目录,其成员是 `/` 子路径而非兄弟 `·` 槽。 +1. **memindex 标记**:值容器主槽 `{key}` 的兄弟槽 `{key}·`,存该容器的成员名索引。**仅** + stringkeymap/struct 用。 +2. **包·函数命名分隔符**:`/lib/{pkg}·{func}`(如 `/lib/time·now`)中的 `·` 只是路径名里分隔包名与函 + 数名的字符,是 rwfunc 所在**目录的名字的一部分**,与 memindex 无关。故 `/lib/time·now/` 仍是纯 + `/` 目录,其成员是 `/` 子路径而非兄弟 `·` 槽。 -两类值容器底层皆为同一 m×n 对齐字符串数组:目录节点由 kvspace 目录直接持有并按 `/` 枚举,值容器把它放在 `{key}·` 兄弟槽。 +两类值容器底层皆为同一 m×n 对齐字符串数组:目录节点由 kvspace 目录直接持有并按 `/` 枚举,值容器把它 +放在 `{key}·` 兄弟槽。 ### rwir 无实现体(叶子)vs rwfunc 有实现体(目录);def 族定义节点 @@ -42,15 +49,24 @@ storetype=index/extindex 只表「这是有成员的索引节点」,成员的* | `def rwir` | 无(仅签名,无指令行) | **仅 `/lib/`** | runtime 直接兑现 | index **定义节点**(有签名行 `[0,x]`,无实现指令行) | | `rwfunc` | **有**(一串 rwir 指令行) | `/lib/·/` | kvlang 指令序列自身 | index/extindex **目录**(签名行 `[0,x]` + 实现指令行 `[s0>0,·]`) | -**def rwir 是路由头**(原 `defrwir`,现规范书写为带空格的 **`def rwir`**,见下「def 族」):它只存在于 `/lib/`,是每个 rwir 指令的统一声明入口。`/vthread/` 下执行的每条 rwir 都**引用** `/lib/` 的 def rwir——为「rwir 统一调度」而设。def rwir 没有 kvlang 实现体(无 `s0>0` 的实现指令行),由 runtime 直接兑现。 +**def rwir 是路由头**(原 `defrwir`,现规范书写为带空格的 **`def rwir`**,见下「def 族」):它只存在 +于 `/lib/`,是每个 rwir 指令的统一声明入口。`/vthread/` 下执行的每条 rwir 都**引用** `/lib/` +的 def rwir——为「rwir 统一调度」而设。def rwir 没有 kvlang 实现体(无 `s0>0` 的实现指令行),由 +runtime 直接兑现。 -**没有「扩展 rwir」这个说法**:def rwir 不专指扩展算子。每个 runtime 只声明自己的 **myrwircaps**(该 runtime 能兑现的 rwir 能力集),`/lib/` 的 def rwir 即这些能力对外的路由头。 +**没有「扩展 rwir」这个说法**:def rwir 不专指扩展算子。每个 runtime 只声明自己的 **myrwircaps**(该 +runtime 能兑现的 rwir 能力集),`/lib/` 的 def rwir 即这些能力对外的路由头。 -rwfunc 与之相反:它**有** kvlang 实现体——就是它 `/` 目录下的实现指令行子成员(`/lib/pkg·funca/[1,0]`…)。这正是 rwir/def rwir(无实现指令行、runtime 兑现)与 rwfunc(有实现指令行、`/` 目录)的本质区别。 +rwfunc 与之相反:它**有** kvlang 实现体——就是它 `/` 目录下的实现指令行子成员 +(`/lib/pkg·funca/[1,0]`…)。这正是 rwir/def rwir(无实现指令行、runtime 兑现)与 rwfunc(有实现指令 +行、`/` 目录)的本质区别。 **为何有 def rwir 却无 def rwfunc**——根源在能力调度的不对称: -- **rwfunc 可被任意 main-runtime 直接解释执行**:其实现体就是一串 rwir,main-runtime 逐条解释即可,不需路由头。故 rwfunc 无需、也没有 `def rwfunc`。 -- **rwir 若不在本 runtime 的 myrwircaps 内就执行不了**,必须依赖调度转发给**能兑现它的其它 runtime**。这份「按能力路由到其它 runtime」的需求,正由 `/lib/` 的 **def rwir 路由头**承载——这就是 def rwir 存在的根本原因。 +- **rwfunc 可被任意 main-runtime 直接解释执行**:其实现体就是一串 rwir,main-runtime 逐条解释即可, + 不需路由头。故 rwfunc 无需、也没有 `def rwfunc`。 +- **rwir 若不在本 runtime 的 myrwircaps 内就执行不了**,必须依赖调度转发给**能兑现它的其它 + runtime**。这份「按能力路由到其它 runtime」的需求,正由 `/lib/` 的 **def rwir 路由头**承载——这 + 就是 def rwir 存在的根本原因。 "#### -> /lib/kvlang/spec/类型系统/storetype物理布局 } 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 387e5c7..100ff7e 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" @@ -4,22 +4,42 @@ lib kvlang/spec/类型系统/storetype_def族与签名行 { ### 签名不入 langtype 串,而入签名行 `[0,x]` 槽 -rwfunc / def rwir 的**签名(各参数类型)不写进 langtype 串**,也不塞进主槽 body。分两处存: - -1. **主槽计数头**:目录节点主槽 `{fn}`(如 `/lib/pkg·funca`)的 body 只记 `[nr:u16 LE][nw:u16 LE][dynamic:u8]`——读参个数 `nr`、写参个数 `nw`、是否变参 `dynamic`(末位读参 `...`)。**不含任何参数 langtype 串**。 -2. **签名行 `[0,x]` 各槽**:每个参数的真实类型定义落在该目录的**签名行**坐标 `[0,x]`——`x<0` 为读参、`x>0` 为写参、`[0,0]` 为 opcode/签名行锚点(见 [[指令布局格式]] 的二元坐标 `[s0,s1]`:`s0=0` 即签名行)。每个 `[0,x]` 槽是一个 **`def langtype`** 类型的 xvalue,其 body 存该参数的完整 langtype 串(一个参数一槽),**纯净、不含参数变参 `...`**——变参是 arity,只落主槽 `dynamic` 字节(见 [[函数]])。 - -于是 rwfunc/def rwir 主槽的 langtype 就是裸种类名 `rwfunc` / `def rwir` 本身,**不再是「签名 langtype 串」**。签名分散在 `[0,x]` 签名行槽里,实现指令行(若有)在 `[s0>0,·]`。 +> **铁律**:任何 rwir/rwfunc 值的 body = `[nr][nw][dynamic]` 计数,仅此而已。参数类型的承载则按种类 + 分 + 两路:**def rwir** 每参独占一个 `[0,x]` 参数轴坐标 key(位置化);**rwfunc** 不落 `[0,x]`,改由命 + 名 + 参数键 `{name}` 的 Ptr(其 langtype 即该参类型)承载(按名解析)。 + +rwfunc / def rwir 的**签名(各参数类型)不写进 langtype 串**,也不塞进主槽 body。主槽只记计数头,参 +数 +类型按种类分路承载: + +1. **主槽计数头**(两者共有):目录节点主槽 `{fn}`(如 `/lib/pkg·funca`)的 body 只记 + `[nr:u16 LE][nw:u16 LE][dynamic:u8]`——读参个数 `nr`、写参个数 `nw`、是否变参 `dynamic`(末位读参 + `...`)。**不含任何参数 langtype 串**。 +2. **def rwir——位置化 `[0,x]` 签名槽**:每个参数类型落该目录签名行坐标 `[0,x]`——`x<0` 读参、`x>0` + 写参、`[0,0]` 为锚点(见 [[指令布局格式]] 二元坐标 `[s0,s1]`,`s0=0` 即签名行)。每个 `[0,x]` 是 + **`def langtype`** xvalue,body 存该参数完整 langtype 串(一参一槽),**纯净、不含变参 `...`**—— + 变 + 参是 arity,只落主槽 `dynamic` 字节。跨 runtime 队列按位置收参,故须有序签名。 +3. **rwfunc——命名参数键 `{name}` 承载**:func 目录根**不**落 `[0,x]` 槽;每个参数类型随命名参数键 + `funcDir/{name}` 的 Ptr 承载——该 Ptr body 为槽坐标(读参 `[0,-j]`、写参 `[0,+j]`),**其 langtype + 即该参数完整类型串**。rwfunc 按名在帧内解析,不在意参数顺序、仅区分读/写参。 + +于是 rwfunc/def rwir 主槽 langtype 都是裸种类名 `rwfunc` / `def rwir` 本身,**非「签名 langtype +串」**。def rwir 的签名散在 `[0,x]` 槽、rwfunc 的散在 `{name}` Ptr;实现指令行(若有)在 +`[s0>0,·]`。 ### def 族:定义节点的 langtype(带空格书写) -「某类型的定义节点」自身的 langtype 用 **`def `** 家族名,**中间保留空格**(读作「`base` 的定义」): +「某类型的定义节点」自身的 langtype 用 **`def `** 家族名,**中间保留空格**(读作「`base` 的定 +义」): | langtype | 落点 | 表示 | |----------|------|------| | `def rwir` | `/lib/` | 一条 rwir 的路由头/签名定义(原 `defrwir`,废连写) | | `def struct` | `/lib/` | 一个 struct 原型的定义节点(字段类型定义在其子槽) | -| `def langtype` | 签名行 `[0,x]` 槽 | 一个参数的类型定义(body=该参数 langtype 串) | +| `def langtype` | def rwir 签名行 `[0,x]` 槽 | 一个参数的类型定义(body=该参数 langtype 串;rwfunc 不用此槽,类型随 `{name}` Ptr 的 langtype 承载) | `def` 与 base 间的空格是**规范强制**:连写形式 `defrwir`/`defstruct`/`deflangtype` 一律废除。 @@ -30,7 +50,7 @@ KV 树中的目录路径(尾 `/`)本身是 xvalue,storetype ∈ {index, ex | 路径 | langtype | storetype | 成员 | |------|----------|-----------|------| | `/lib/` | `lib` | index | `/lib/` 各包目录(`/` 子路径) | -| `/lib/pkg·funca/` | `rwfunc` | index(静态函数定义目录) | 签名行 `[0,x]`(def langtype)+ 实现指令行 `[s0>0,·]` | +| `/lib/pkg·funca/` | `rwfunc` | index(静态函数定义目录) | 命名参数键 `{name}`(Ptr,langtype=参类型)+ 实现指令行 `[s0>0,·]` | | `/lib/` | `def rwir` | index(路由头,只有签名行) | 签名行 `[0,x]`(def langtype),无实现指令行 | | `/vthread/1/` | `rwfunc` | extindex(运行栈,可扩展) | `/vthread/1/<坐标>` 栈帧/指令 | 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 8f993d3..1220cb4 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,9 @@ lib kvlang/spec/类型系统/langtype语义类型 { r####"# langtype(语义类型维,语言视角) -本章界定 **value langtype**——一个具体值 head 的 langtype(两型 def/value 与 kindexpr 简写见 [[langtype签名类型表达式]])。langtype 是完整的类型表达式串,逐字节即类型标注文法,天然含 base 种类、`[dims]`、map 键值、struct 原型路径。各 langtype 的串形态与其落定的 storetype: +本章界定 **value langtype**——一个具体值 head 的 langtype(两型 def/value 与 kindexpr 简写见 +[[langtype签名类型表达式]])。langtype 是完整的类型表达式串,逐字节即类型标注文法,天然含 base 种 +类、`[dims]`、map 键值、struct 原型路径。各 langtype 的串形态与其落定的 storetype: | langtype(示例串) | storetype | 说明 | |--------------------------|-----------|------| @@ -16,13 +18,19 @@ lib kvlang/spec/类型系统/langtype语义类型 { | `/lib/Point`(struct 原型路径) | index | 结构实例,字段固定;成员在 `{key}·` | | `def struct`(原型定义节点) | index | struct 原型自身;字段类型定义在其子槽 | | `rwfunc` | index / extindex | 函数即 `/` 目录:签名行 `[0,x]` + 实现指令行;主槽 body 只记 nr/nw/dynamic | -| `def langtype`(签名行 `[0,x]` 槽) | ARRAYND | 单个参数类型定义,body=该参数 langtype 串 | +| `def langtype`(签名行 `[0,x]` 槽) | ATOM | 单个参数类型定义,body=该参数 langtype 串 | | `lib`(包目录) | index | `/lib/` 及各 pkg 目录;成员为 `/` 子路径 | -**def 族的来源**(`def` 不是 kvlang 关键字、不在 kv 源码书写):`def struct`(源码 `struct Name{}`,layout 落原型定义节点)、`def langtype`(源码参数标注 `x:int64`,layout 铺签名行时逐参生成)由 **layout** 产生;`def rwir`(`/lib/` 路由头)**由各 runtime 注册**——kv 源码不声明 rwir,layout 也不产生 def rwir(见 [[rwfunc布局与def_rwir]])。 +**def 族的来源**(`def` 不是 kvlang 关键字、不在 kv 源码书写):`def struct`(源码 `struct Name{}`, +layout 落原型定义节点)、`def langtype`(源码参数标注 `x:int64`,layout 铺签名行时逐参生成)由 +**layout** 产生;`def rwir`(`/lib/` 路由头)**由各 runtime 注册**——kv 源码不声明 rwir,layout +也不产生 def rwir(见 [[rwfunc布局与def_rwir]])。 -`object`/`scope` **彻底不存在**——无此种类名、无此关键字;异构命名容器一律是 `struct`(见 [[容器]])。容器**语义类型**只剩 `stringkeymap`、`struct`(口语称「map」指的即 stringkeymap,规范一律书写种类名 `stringkeymap`)。 +`object`/`scope` **彻底不存在**——无此种类名、无此关键字;异构命名容器一律是 `struct`(见 [[容 +器]])。容器**语义类型**只剩 `stringkeymap`、`struct`(口语称「map」指的即 stringkeymap,规范一律书 +写种类名 `stringkeymap`)。 -**一对多正是拆分的价值**:同为 rwfunc,静态函数定义落 `index`、vthread 运行栈落 `extindex`;语言层看到的是同一 langtype,物理层按场景选载体。 +**一对多正是拆分的价值**:同为 rwfunc,静态函数定义落 `index`、vthread 运行栈落 `extindex`;语言层看 +到的是同一 langtype,物理层按场景选载体。 "#### -> /lib/kvlang/spec/类型系统/langtype语义类型 } 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 2b92aea..ba0df31 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" @@ -2,7 +2,8 @@ lib kvlang/spec/类型系统/wire布局示例 { r####"# wire 布局示例 -通用前缀 `U = [headlen:u16][ref][storetype][ro][vid:u32][body_len:u32]`,其后按 storetype 追加物理字段,再接 langtype 串(占至 headlen),末接 body: +通用前缀 `U = [headlen:u16][ref][storetype][ro][vid:u32][body_len:u32]`,其后按 storetype 追加物理字 +段,再接 langtype 串(占至 headlen),末接 body: ``` None : U(store=NONE)[lang=""] | 空 @@ -15,7 +16,7 @@ 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/ : U(store=index)[count/cap…][lang="def rwir"] | 路由头;body=[nr][nw][dyn];签名在 [0,x],无实现行 -签名行 [0,x]: U(store=ARRAYND)[lang="def langtype"] | body=该参数 langtype 串 +签名行 [0,x]: U(store=ATOM)[lang="def langtype"] | body=该参数 langtype 串 /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 11d3aaf..06fb838 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" @@ -2,27 +2,40 @@ lib kvlang/spec/类型系统/已敲定 { r####"# 已敲定 -- 三维正交:`ref` × `storetype` × `langtype`,codec 只认 storetype(1 字节)、语言层只认 langtype(即类型表达式串)。 +- 三维正交:`ref` × `storetype` × `langtype`,codec 只认 storetype(1 字节)、语言层只认 langtype + (即类型表达式串)。 - **langtype = 完整类型表达式串**(变长),保留高级语言全部类型定义;1 字节 kindcode 方案作废。 -- storetype 集:`NONE`/`ATOM`/`ARRAYND`/`index`/`extindex`(index/extindex 是 storetype,非 langtype)。 -- 容器语义类型只剩 `stringkeymap`/`struct`(口语「map」= stringkeymap;`object`/`scope` **彻底删除**,无此种类/关键字);物理落 index。 +- storetype 集:`NONE`/`ATOM`/`ARRAYND`/`index`/`extindex`(index/extindex 是 storetype,非 + langtype)。 +- 容器语义类型只剩 `stringkeymap`/`struct`(口语「map」= stringkeymap;`object`/`scope` **彻底删除 + **,无此种类/关键字);物理落 index。 - 字符串:ascii/utf32 → ARRAYND;utf8 → ARRAYND(elem 1B)。 - time/duration → ATOM;rwir 指令行 → ARRAYND 叶子(无实现体)。 -- **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 串)。 -- **def 族带空格书写**:`def rwir`、`def struct`、`def langtype`——`def` 与 base 间强制空格,连写形式废除。 +- **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 串)。 +- **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 扩容),沿用今日敲定方案,存成员/子项名。 -- **`·` 双义正交**:① memindex 标记 `{key}·` 仅 stringkeymap/struct 用;② `/lib/{pkg}·{func}` 里的 `·` 是包·函数命名分隔符(路径名一部分),与 memindex 无关,rwfunc 目录成员仍走 `/`。 +- **index/extindex 物理载体 = m×n 对齐字符串数组**(`dims=[len,cap,M]`,M align8、cap 扩容),沿用今 + 日敲定方案,存成员/子项名。 +- **`·` 双义正交**:① memindex 标记 `{key}·` 仅 stringkeymap/struct 用;② `/lib/{pkg}·{func}` 里的 + `·` 是包·函数命名分隔符(路径名一部分),与 memindex 无关,rwfunc 目录成员仍走 `/`。 - 索引型容器(stringkeymap/struct)主槽 `{key}` body 恒空。 -- **源码 `*`/`@` 前缀保留**:kvlang 源码类型标注最前可写 `*`/`@`(表 ref),layout 剥离前缀落成 head `ref` 字节;wire 层 langtype 串不含前缀。 +- **源码 `*`/`@` 前缀保留**:kvlang 源码类型标注最前可写 `*`/`@`(表 ref),layout 剥离前缀落成 head + `ref` 字节;wire 层 langtype 串不含前缀。 - `headlen` u16 LE;`body_len` 保留为显式 u32 LE 字段;langtype 串占至 headlen,无独立长度字段。 - `ref=2`(@ext)与 index/extindex 无关。 - in-memory head struct 按 storetype 拆分——**属实现层,本规范只定 wire 与字段语义**。 ## 仍待敲定 -(本卷所有类型分歧已敲定。剩余仅实现层细节——如 index/extindex m×n 数组各字段精确偏移、签名行 `[0,x]` 坐标与 [[指令布局格式]] 二元坐标的具体编码、extindex 扩容策略——随 01-04 重构与 [[容器]] memindex 线格式对齐后落定,不属本卷规范分歧。) +(本卷所有类型分歧已敲定。剩余仅实现层细节——如 index/extindex m×n 数组各字段精确偏移、签名行 `[0,x]` +坐标与 [[指令布局格式]] 二元坐标的具体编码、extindex 扩容策略——随 01-04 重构与 [[容器]] memindex 线 +格式对齐后落定,不属本卷规范分歧。) "#### -> /lib/kvlang/spec/类型系统/已敲定 } diff --git "a/stdlib/kvlang/spec/03-\347\261\273\345\236\213\347\263\273\347\273\237/26-\345\255\227\347\254\246\344\270\262\347\274\226\347\240\201.kv" "b/stdlib/kvlang/spec/03-\347\261\273\345\236\213\347\263\273\347\273\237/26-\345\255\227\347\254\246\344\270\262\347\274\226\347\240\201.kv" index de1a94d..565fe5d 100644 --- "a/stdlib/kvlang/spec/03-\347\261\273\345\236\213\347\263\273\347\273\237/26-\345\255\227\347\254\246\344\270\262\347\274\226\347\240\201.kv" +++ "b/stdlib/kvlang/spec/03-\347\261\273\345\236\213\347\263\273\347\273\237/26-\345\255\227\347\254\246\344\270\262\347\274\226\347\240\201.kv" @@ -12,7 +12,8 @@ kvlang 体系内,**key 与 value 中的字符串默认 utf8**。 - key 侧:字符串键(`[]char/utf8·value` 中 key 侧的 `[]char/`)与路径名,utf8 是默认。 - value 侧:落到 KV 树的字符串值,未显式标注时以 utf8 承载。 -utf8 是变宽字节序列,**字节取向、空间高效**,适合作为持久/交换形态;utf8 **禁码点索引**(O(1) 索引须定宽编码)。 +utf8 是变宽字节序列,**字节取向、空间高效**,适合作为持久/交换形态;utf8 **禁码点索引**(O(1) 索引须 +定宽编码)。 ## 二、utf32 开放给用户 kv 代码 @@ -25,7 +26,8 @@ char/utf32(s8) -> s32 // s32: []char/utf32,定宽可索引 s32[0] -> c // O(1) 码点取 ``` -utf8 → utf32 的转换是**显式**的(编码纪律,见 [[字符串与空值布尔字面量]] 与 char 转换 builtin);跨编码不隐式混拼。 +utf8 → utf32 的转换是**显式**的(编码纪律,见 [[字符串与空值布尔字面量]] 与 char 转换 builtin);跨 +编码不隐式混拼。 ## 三、string 标准库只处理定宽(utf32) diff --git "a/stdlib/kvlang/spec/04-layout\350\257\255\344\271\211/01-\346\214\207\344\273\244\346\236\266\346\236\204.kv" "b/stdlib/kvlang/spec/04-layout\350\257\255\344\271\211/01-\346\214\207\344\273\244\346\236\266\346\236\204.kv" index 4b11abc..ea48e4f 100644 --- "a/stdlib/kvlang/spec/04-layout\350\257\255\344\271\211/01-\346\214\207\344\273\244\346\236\266\346\236\204.kv" +++ "b/stdlib/kvlang/spec/04-layout\350\257\255\344\271\211/01-\346\214\207\344\273\244\346\236\266\346\236\204.kv" @@ -2,13 +2,17 @@ lib kvlang/spec/layout语义/指令架构 { r####"# 指令架构 -layout 把每个函数体布进 kvspace 的一棵子树:**指令即路径**,每条指令占据一个二维坐标 `[s0, s1]`。本章界定该坐标系、opcode 与读写槽的角色、两种赋值书写形态,以及槽值的 XValue 编码。二维坐标的线格式(TLV、head langtype)见 [[指令布局格式]](kvspace 模型卷);本章只界定 layout 产出的槽位语义。 +layout 把每个函数体布进 kvspace 的一棵子树:**指令即路径**,每条指令占据一个二维坐标 `[s0, s1]`。本 +章界定该坐标系、opcode 与读写槽的角色、两种赋值书写形态,以及槽值的 XValue 编码。二维坐标的线格式 +(TLV、head langtype)见 [[指令布局格式]](kvspace 模型卷);本章只界定 layout 产出的槽位语义。 ## 二维坐标系 `[s0, s1]` -函数目录(`/lib/·/`,见 [[lib与rwir数据]])下,每条指令的每个槽是一个独立 KV key,key 名恒为坐标串 `[s0,s1]`。两轴含义: +函数目录(`/lib/·/`,见 [[lib与rwir数据]])下,每条指令的每个槽是一个独立 KV key,key 名 +恒为坐标串 `[s0,s1]`。两轴含义: -- **s0 轴(执行顺序轴)**——第几条指令。`s0 = 0` 保留给函数签名行;指令从 `s0 = 1` 起顺序编号(称 irseq)。 +- **s0 轴(执行顺序轴)**——第几条指令。`s0 = 0` 保留给函数签名行;指令从 `s0 = 1` 起顺序编号(称 + irseq)。 - **s1 轴(参数轴)**——该槽的角色: | s1 | 角色 | 方向 | @@ -21,7 +25,8 @@ layout 把每个函数体布进 kvspace 的一棵子树:**指令即路径**, - `[s0, 0]` **必须**是 opcode(操作符名或被调用的 rwir/rwfunc 名),**不得**放变量引用。 - 读参在负轴、写参在正轴,符号即数据流方向:从负轴读入、在零轴执行、向正轴写出。 -- 参数数量**隐式编码**:runtime 沿 s1 轴向两侧扩展,遇空 key 即停,opcode 中不存 arity(见 [[执行模型]])。 +- 参数数量**隐式编码**:runtime 沿 s1 轴向两侧扩展,遇空 key 即停,opcode 中不存 arity(见 [[执行模 + 型]])。 示例:`A + B -> C` 布为 @@ -32,7 +37,8 @@ layout 把每个函数体布进 kvspace 的一棵子树:**指令即路径**, [s0,1] = "C" 第 1 写参 ``` -写参扇出(同一结果写入多个位置)以多个正轴槽表示:`a + b -> sum, backup` 布出 `[s0,1]="sum"`、`[s0,2]="backup"`。 +写参扇出(同一结果写入多个位置)以多个正轴槽表示:`a + b -> sum, backup` 布出 `[s0,1]="sum"`、 +`[s0,2]="backup"`。 ## 两种赋值书写形态 @@ -43,13 +49,22 @@ layout 把每个函数体布进 kvspace 的一棵子树:**指令即路径**, | `expr -> writes` | 左读、右写 | 右 | `A + B -> C` | | `writes = expr` | 左写、右读 | 左 | `C = A + B` | -- `->` **契合参数轴布局**:读参在负轴 `[s0,-n]`、写参在正轴 `[s0,+n]`,数据从负轴读入、经零轴 opcode、向正轴写出(见上「二维坐标系」)。书写时同样是「左读、右写」,箭头方向即数据流方向,与数学坐标系「负 → 正」的直觉一致。 +- `->` **契合参数轴布局**:读参在负轴 `[s0,-n]`、写参在正轴 `[s0,+n]`,数据从负轴读入、经零轴 + opcode、向正轴写出(见上「二维坐标系」)。书写时同样是「左读、右写」,箭头方向即数据流方向,与数学 + 坐标系「负 → 正」的直觉一致。 - `=` **沿用主流编程语言习惯**:左写、右读,便于带着 C/Python/Rust/Go/JS 直觉的使用者上手。 -两形态语义等价,同一次赋值只取一种方向,可按可读性择一。`=` 与 `->` **不是**表达式,**不得**嵌套于条件或实参中;相等比较写作 `==`。(历史上曾有第三种 `<-`(左写),与 `=` 完全重复,已删除——写槽在左一律写 `=`。) +两形态语义等价,同一次赋值只取一种方向,可按可读性择一。`=` 与 `->` **不是**表达式,**不得**嵌套于条 +件或实参中;相等比较写作 `==`。(历史上曾有第三种 `<-`(左写),与 `=` 完全重复,已删除——写槽在左一 +律写 `=`。) -**落入 kvspace 一律是 `->` 轴结构。** `=` 只是单条指令「写左」的源码别名,方便书写;无论源码写 `=` 还是 `->`,layout 落入 kvspace 后的 rwir 与 rwfunc 签名**一致**按 `->` 的「左读 / 右写」轴布局——读参在负轴 `[s0,-n]`、写参在正轴 `[s0,+n]`。因此 rwfunc 签名的对外接口 `(读参) -> (写参)`、签名行 `[0,·]` 只用 `->` 形态表达,没有 `=` 形式的签名(见 [[函数]])。`=` 从不改变槽位布局,仅决定同一条指令里写槽写在源码的哪一侧。 +**落入 kvspace 一律是 `->` 轴结构。** `=` 只是单条指令「写左」的源码别名,方便书写;无论源码写 `=` +还是 `->`,layout 落入 kvspace 后的 rwir 与 rwfunc 签名**一致**按 `->` 的「左读 / 右写」轴布局——读参 +在负轴 `[s0,-n]`、写参在正轴 `[s0,+n]`。因此 rwfunc 签名的对外接口 `(读参) -> (写参)`、签名行 +`[0,·]` 只用 `->` 形态表达,没有 `=` 形式的签名(见 [[函数]])。`=` 从不改变槽位布局,仅决定同一条指 +令里写槽写在源码的哪一侧。 -**写槽必须是位置(location)**:裸名(帧内变量)、绝对路径(`/abs`)、成员写(`base·field` / `base·*key`)、下标写(`arr[idx]`)。字面量出现在写槽位置是错误,layout 报诊断(见 [[诊断]])。 +**写槽必须是位置(location)**:裸名(帧内变量)、绝对路径(`/abs`)、成员写(`base·field` / +`base·*key`)、下标写(`arr[idx]`)。字面量出现在写槽位置是错误,layout 报诊断(见 [[诊断]])。 "#### -> /lib/kvlang/spec/layout语义/指令架构 } 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 5509ff2..f5fe1ea 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" @@ -11,24 +11,30 @@ a -> b [s0,0]="=" [s0,-1]="a" [s0,1]="b" 42 -> x [s0,0]="=" [s0,-1]=42 [s0,1]="x" ``` -opcode 位恒为操作码,故拷贝(opcode=`=`)与零参函数调用(`greet() -> x`,opcode=`greet`)在 KV 层无歧义。 +opcode 位恒为操作码,故拷贝(opcode=`=`)与零参函数调用(`greet() -> x`,opcode=`greet`)在 KV 层无 +歧义。 ## opcode 槽的 langtype 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数据]])。 ## 读写槽的槽值编码 读/写槽的槽值按内容编码为 XValue: -- 字面量(整数、浮点、`true`/`false`、字符串、绝对路径)——按其类型编码为对应 kind 的 XValue(`int64` / `float64` / `bool` / `char/*` …);字符串字面量在 KV 传输层以 `"` 前缀区分于变量名。 +- 字面量(整数、浮点、`true`/`false`、字符串、绝对路径)——按其类型编码为对应 kind 的 XValue(`int64` + / `float64` / `bool` / `char/*` …);字符串字面量在 KV 传输层以 `"` 前缀区分于变量名。 - 变量名、标签等引用——langtype `rwir`,body 即该名字符串。 ## 增量覆盖 -写函数前 layout **必须**先 `del_tree` 清除该函数子树,再重写:残留的旧槽会被 runtime 沿 s1 轴误读为真实参数。清除**仅限本函数子树**——多次 layout 各自覆盖其函数,**不得**整库删除,以支持增量布局(文件夹复制式合并)。 +写函数前 layout **必须**先 `del_tree` 清除该函数子树,再重写:残留的旧槽会被 runtime 沿 s1 轴误读为 +真实参数。清除**仅限本函数子树**——多次 layout 各自覆盖其函数,**不得**整库删除,以支持增量布局(文件 +夹复制式合并)。 "#### -> /lib/kvlang/spec/layout语义/指令槽编码 } 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 7019769..141fcdb 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" @@ -2,9 +2,14 @@ lib kvlang/spec/layout语义/函数 { r####"# 函数 -kvlang 源码只有一种命名单元:**rwfunc**(有指令体的用户函数),暴露 `(读参) -> (写参)` 箭头接口。函数**没有返回值**,只有读参与写参。 +kvlang 源码只有一种命名单元:**rwfunc**(有指令体的用户函数),暴露 `(读参) -> (写参)` 箭头接口。函 +数**没有返回值**,只有读参与写参。 -签名与体内 rwir 落入 kvspace 的布局**一律**按 `->` 的「左读 / 右写」轴实现:读参在负轴、写参在正轴(见 [[指令架构]])。`=` 只存在于 kvlang 上层 code 层,是单条指令「写左」的书写别名,不进入签名、也不改变槽位布局——所以没有 `=` 形式的 rwfunc 签名,接口只用 `(读参) -> (写参)` 表达。rwir 是 runtime 兑现的原子能力,源码**不声明**、只调用;其 `def rwir` 路由头由各 runtime 注册到 `/lib`(见 [[rwfunc布局与def_rwir]])。 +签名与体内 rwir 落入 kvspace 的布局**一律**按 `->` 的「左读 / 右写」轴实现:读参在负轴、写参在正轴 +(见 [[指令架构]])。`=` 只存在于 kvlang 上层 code 层,是单条指令「写左」的书写别名,不进入签名、也 +不改变槽位布局——所以没有 `=` 形式的 rwfunc 签名,接口只用 `(读参) -> (写参)` 表达。rwir 是 runtime +兑现的原子能力,源码**不声明**、只调用;其 `def rwir` 路由头由各 runtime 注册到 `/lib`(见 [[rwfunc +布局与def_rwir]])。 ## 读参与写参 @@ -13,13 +18,18 @@ kvlang 源码只有一种命名单元:**rwfunc**(有指令体的用户函数 | **读参** | `[0,-1], [0,-2], …` | 调用方 → 被调方 | | **写参** | `[0,+1], [0,+2], …` | 被调方 → 调用方 | -`-> result` 是**写参的跨帧路径映射**,不是返回值:runtime 将子帧写参直写调用方目标位置(见 [[函数调用与内建]])。 +`-> result` 是**写参的跨帧路径映射**,不是返回值:runtime 将子帧写参直写调用方目标位置(见 [[函数调 +用]])。 -调用时**写参 arity 必须全部匹配**(对齐 Go/Rust):`f() -> s` 对多写参函数是错误;不需要的写参**必须**用 `_` 显式丢弃。 +调用时**写参 arity 必须全部匹配**(对齐 Go/Rust):`f() -> s` 对多写参函数是错误;不需要的写参**必须 +**用 `_` 显式丢弃。 ## 参数类型必须标注 -每个读参与写参**必须**声明类型(`name:type_expr`,type_expr 见 [[langtype签名类型表达式]])。type_expr 最前可写 `*`/`@` 前缀(如 `*int64`、`@[256,256]uint8`)表示 ptr/ext 存储位置;layout 解析时剥离该前缀并落成 head `ref` 字节,wire 层 langtype 串不含前缀(见 [[总体方案]])。缺类型标注是错误: +每个读参与写参**必须**声明类型(`name:type_expr`,type_expr 见 [[langtype签名类型表达式]])。 +type_expr 最前可写 `*`/`@` 前缀(如 `*int64`、`@[256,256]uint8`)表示 ptr/ext 存储位置;layout 解析 +时剥离该前缀并落成 head `ref` 字节,wire 层 langtype 串不含前缀(见 [[总体方案]])。缺类型标注是错 +误: ``` error: func f: param "x" has no type annotation — every parameter must declare its type @@ -28,19 +38,27 @@ error: func f: return value "r" has no type annotation ## 参数变参(arity,非类型) -末读参**可**在参数上尾缀 `...` 声明变参(吸收 0..N 个同型实参,如 `A:int64|float64...`)。`...` 是**签名层 arity 构造,不是 type_expr 的一部分**(轴量词见 [[langtype签名类型表达式]]):layout 解析时把它从参数上**剥离**,给该函数主槽置 `dynamic=1`(见 [[指令布局格式]]),而参数的 langtype 子槽 `[0,x]` 存**纯净** langtype(不含 `...`)。故 `LangtypeValid`/`LangtypeMatch` 永不见 `...`。 +末读参**可**在参数上尾缀 `...` 声明变参(吸收 0..N 个同型实参,如 `A:int64|float64...`)。`...` 是** +签名层 arity 构造,不是 type_expr 的一部分**(轴量词见 [[langtype签名类型表达式]]):layout 解析时把 +它从参数上**剥离**,给该函数主槽置 `dynamic=1`(见 [[指令布局格式]]),而参数的**纯净** langtype(不含 +`...`)由承载点存放——def rwir 落 `[0,x]` 子槽、rwfunc 随 `{name}` Ptr 的 langtype。故 +`LangtypeValid`/`LangtypeMatch` 永不见 `...`。 - 变参**必须**是最后一个读参;非末位读参带 `...`:装载期错误。 - 写参(返回值)**不得**变参:装载期错误。 -- 派发时,主槽 `dynamic=1` 则末读参对每个尾随实参按其纯净 langtype 逐个判定(见 [[匹配语义与变参]])。 +- 派发时,主槽 `dynamic=1` 则末读参对每个尾随实参按其纯净 langtype 逐个判定(见 [[匹配语义与变 + 参]])。 ## 写参初值 None -写参在被调方帧内初值为 **None**(strict null)。函数体内**必须**先显式初始化写参再参与运算——对 None 做算术在 runtime 被拒。惯例以拷贝置零值起步(`0 -> acc`),此后写参在体内可读可写,退出时经箭头映射回调用方。 +写参在被调方帧内初值为 **None**(strict null)。函数体内**必须**先显式初始化写参再参与运算——对 None +做算术在 runtime 被拒。惯例以拷贝置零值起步(`0 -> acc`),此后写参在体内可读可写,退出时经箭头映射 +回调用方。 ## 读参只读 -读参是单向输入绑定。函数体内把读参裸名放入写槽(含 `for … in` 的迭代变量)会破坏数据流方向,layout 报错拒绝装载: +读参是单向输入绑定。函数体内把读参裸名放入写槽(含 `for … in` 的迭代变量)会破坏数据流方向,layout +报错拒绝装载: ``` error: func f: read param "A" cannot be used as write slot (read params are read-only) @@ -55,11 +73,13 @@ rwfunc sum(arr:[]int64, acc:int64) -> (r:int64) { acc + arr[0] -> acc } rwfunc sum(arr:[]int64) -> (acc:int64) { acc + arr[0] -> acc } ``` -判定规则(实现):写槽含 `/`、`[`、`·` 者视为路径/下标/成员写,不计入本检查;但 `kv·set(base, …)` 的 base 命中读参裸名同样拒绝(成员目录被改写)。 +判定规则(实现):写槽含 `/`、`[`、`·` 者视为路径/下标/成员写,不计入本检查;但 `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 174feed..cf1f8aa 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" @@ -15,21 +15,31 @@ lib kvlang/spec/layout语义/函数写槽与布局 { rwfunc 布进 `/lib/·/`: -1. `[0,0]`——签名行锚点,langtype `rwfunc`,body `[nr:u16 LE][nw:u16 LE][dynamic:u8]`(读参数/写参数/是否变参);各参数类型落在签名行 `[0,x]` 槽(`x<0` 读参、`x>0` 写参),每槽为 `def langtype` xvalue,body 即该参数 langtype 串(见 [[总体方案]])。 +1. `[0,0]`——签名行锚点,langtype `rwfunc`,body `[nr:u16 LE][nw:u16 LE][dynamic:u8]`(读参数/写参数/ + 是否变参),仅此计数头。rwfunc **不**在 func 目录根落 `[0,±k]` 参数类型槽——各参类型改由命名参数 + 键承载(见下)。 2. `/lib/·.src`——源码副本(kind `char`)。 -3. 每个命名参数——`funcDir/` 存 Ptr(kind `char`),指向其槽坐标串(读参 `[0,-j]`、写参 `[0,+j]`)。 -4. 指令体从 `[1,0]` 起(`[0,*]` 为签名行占用)。 +3. 每个命名参数——`funcDir/` 存 Ptr,body 为其帧坐标串(读参 `[0,-j]`、写参 `[0,+j]`), + **Ptr 的 langtype 即该参数类型**(target_langtype)——类型随参数名承载,非固定 `char`。 +4. 指令体从 `[1,0]` 起(`[0,0]` 为签名行锚点)。 + +func 目录根之所以**不**预落 `[0,±k]`:这些坐标是 runtime 调用期写入的帧本地实参地址;若 layout 提前 +落为只读静态槽,建帧 extindex 后调用期对同坐标的帧本地绑定会触发 extindex 写保护而丢参。def rwir 则 +相反——按位置跨 runtime 派发,仍在 `[0,x]` 落 `def langtype` 静态签名槽(见 [[rwfunc布局与 +def_rwir]])。 写参不需要值的调用以 `_` 接收,`_` 写入帧内 `_` 槽、不影响语义。 ## rwfunc 声明位置 -rwfunc 应包裹在 `lib pkg { }` 内。裸顶层 rwfunc **可**声明,但产生提示(`info`)并登记到 `/lib/`(无 pkg): +rwfunc 应包裹在 `lib pkg { }` 内。裸顶层 rwfunc **可**声明,但产生提示(`info`)并登记到 +`/lib/`(无 pkg): ``` info: rwfunc outside lib block — registering under /lib/; consider wrapping in 'lib pkgname { }' ``` -裸顶层 rwfunc 名与 native builtin 同名是错误(`function "…" shadows builtin`)——须包裹进 lib 或改名。 +裸顶层 rwfunc 名与 native builtin 同名是错误(`function "…" shadows builtin`)——须包裹进 lib 或改 +名。 "#### -> /lib/kvlang/spec/layout语义/函数写槽与布局 } diff --git "a/stdlib/kvlang/spec/04-layout\350\257\255\344\271\211/05-\346\216\247\345\210\266\346\265\201.kv" "b/stdlib/kvlang/spec/04-layout\350\257\255\344\271\211/05-\346\216\247\345\210\266\346\265\201.kv" index 97dafb3..e487130 100644 --- "a/stdlib/kvlang/spec/04-layout\350\257\255\344\271\211/05-\346\216\247\345\210\266\346\265\201.kv" +++ "b/stdlib/kvlang/spec/04-layout\350\257\255\344\271\211/05-\346\216\247\345\210\266\346\265\201.kv" @@ -2,7 +2,8 @@ lib kvlang/spec/layout语义/控制流 { r####"# 控制流 -kvlang 的结构化控制流有 `if`/`else`/`while`/`for … in`/具名 block/`break`/`continue`/`return`。它们**只能**出现在 rwfunc 体内;顶层出现是错误: +kvlang 的结构化控制流有 `if`/`else`/`while`/`for … in`/具名 block/`break`/`continue`/`return`。它们 +**只能**出现在 rwfunc 体内;顶层出现是错误: ``` error: top-level while is not supported — wrap in main() @@ -18,11 +19,14 @@ layout 的 lower 阶段把结构化控制流降级为两条控制原语加具名 - `br(cond, then_label, else_label)`——按 cond 二路分支。 - `break` → `goto` 到循环 exit 块;`continue` → `goto` 到循环 cond 块。 -每个 `if`/`while`/`for` 展开为一组具名块(如 `_while_2`、`_do_3`、`_exit_4`、`_if_5`、`_then_6`、`_else_7`、`_merge_8`)。`else if` 链按嵌套 `if` 展开。开放路径尾部补 `return`(layout 保证每块以终结符 `return`/`goto`/`br` 收尾)。 +每个 `if`/`while`/`for` 展开为一组具名块(如 `_while_2`、`_do_3`、`_exit_4`、`_if_5`、`_then_6`、 +`_else_7`、`_merge_8`)。`else if` 链按嵌套 `if` 展开。开放路径尾部补 `return`(layout 保证每块以终 +结符 `return`/`goto`/`br` 收尾)。 ## 布局为线性 irseq -lower 之后,layout 把**所有**块体展平进函数目录下的**单一线性指令序列** `[1,0]…[N,0]`——**不建 scope 子目录**。goto/br 的跳转目标在布局时解析为**整数 irseq**(目标块首指令的 s0 序号),写入其读槽。 +lower 之后,layout 把**所有**块体展平进函数目录下的**单一线性指令序列** `[1,0]…[N,0]`——**不建 scope +子目录**。goto/br 的跳转目标在布局时解析为**整数 irseq**(目标块首指令的 s0 序号),写入其读槽。 标签到 irseq 的映射另存于 `/lib/·/‥labels/