From 683de2d10e7625e4f56be66a72f1ee0da7a014a5 Mon Sep 17 00:00:00 2001 From: "peng.li24" <734991033@qq.com> Date: Fri, 11 Sep 2026 22:56:40 +0800 Subject: [PATCH] =?UTF-8?q?chore(spec):=20=E6=9C=AF=E8=AF=AD=E6=B8=85?= =?UTF-8?q?=E7=90=86=E2=80=94=E2=80=94&=20=E7=BB=9D=E5=AF=B9=E5=9C=B0?= =?UTF-8?q?=E5=9D=80=E8=BF=90=E7=AE=97=E7=AC=A6=20/=20map=20=E9=94=AE?= =?UTF-8?q?=E4=BE=A7=20formatter?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - & 统一为「绝对地址运算符」:产 ref=1 Ptr(body=绝对路径),非 C 式取址、 非路径串;改 01 词法 08/09、02 寻址、03 ptr、设计理由、附录 03/05/07 - map 键侧 memitemkey → 「键侧 formatter」:键只在路径系统、无 body, 形状 [N]T 不可作键;改 03 文法/map容器/成员访问、附录 03 - json.go: -lkvlang_layout → -lkvlanglayout(库名修正) Co-Authored-By: Claude Opus 4.8 --- runtime-rwirext_example/go/json/json.go | 2 +- ...27\347\254\246\345\237\272\347\241\200.kv" | 2 +- ...16\344\274\230\345\205\210\347\272\247.kv" | 19 ++++++---- ...00\344\270\216\345\221\275\345\220\215.kv" | 4 +- ...16\345\220\210\346\263\225\346\200\247.kv" | 17 ++++++--- .../14-map\345\256\271\345\231\250.kv" | 37 ++++++++++++++----- ...20\345\221\230\350\256\277\351\227\256.kv" | 7 ++-- .../16-ptr.kv" | 6 +-- ...07\347\232\206\346\230\216\346\226\207.kv" | 7 ++-- ...76\345\274\217\346\226\207\346\263\225.kv" | 8 ++-- ...5-\350\241\250\350\276\276\345\274\217.kv" | 2 +- ...05\345\273\272\345\207\275\346\225\260.kv" | 2 +- 12 files changed, 72 insertions(+), 41 deletions(-) diff --git a/runtime-rwirext_example/go/json/json.go b/runtime-rwirext_example/go/json/json.go index 9c835b62..e398bc33 100644 --- a/runtime-rwirext_example/go/json/json.go +++ b/runtime-rwirext_example/go/json/json.go @@ -6,7 +6,7 @@ package json // 后端(kvspace-c=shm / kvspace_durable=redis|fs)由 Makefile 经 CGO_LDFLAGS 注入, // 对齐 term 的 KVLANG_KVSPACE_LIB;扩展宿主自连 kvspace,不经 runtime。 #cgo CFLAGS: -I${SRCDIR}/../../../runtime/include -#cgo LDFLAGS: -L${SRCDIR}/../../../bin -lkvlang_runtime -L${SRCDIR}/../../../layout/target/release -lkvlang_layout -Wl,-rpath,${SRCDIR}/../../../bin -Wl,-rpath,${SRCDIR}/../../../layout/target/release +#cgo LDFLAGS: -L${SRCDIR}/../../../bin -lkvlang_runtime -L${SRCDIR}/../../../layout/target/release -lkvlanglayout -Wl,-rpath,${SRCDIR}/../../../bin -Wl,-rpath,${SRCDIR}/../../../layout/target/release #include "kvlang_rwirext.h" #include #include 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 1e18ea58..0c8ee32d 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" @@ -44,7 +44,7 @@ x = 42 // 左写、右读 - `/`(U+002F)**不是**除号。它只用于绝对路径字面量与注释(`//`、`/*`);出现在其他位置的裸 `/` 不承 载算术除法语义。 -一元 `+`、`-` 作前缀;`√`(U+221A,平方根)亦为一元前缀运算符。`&` 亦兼一元前缀(取址, +一元 `+`、`-` 作前缀;`√`(U+221A,平方根)亦为一元前缀运算符。`&` 亦兼一元前缀(**绝对地址**, `&x ≡ kv·abs(x)`);其中缀身份(按位与)与前缀身份靠位置区分,同 C,详见 [[逻辑位运算与优先级]]。 ## 比较运算符 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 9856219d..da37f4df 100644 --- "a/stdlib/kvlang/spec/01-\350\257\215\346\263\225/09-\351\200\273\350\276\221\344\275\215\350\277\220\347\256\227\344\270\216\344\274\230\345\205\210\347\272\247.kv" +++ "b/stdlib/kvlang/spec/01-\350\257\215\346\263\225/09-\351\200\273\350\276\221\344\275\215\350\277\220\347\256\227\344\270\216\344\274\230\345\205\210\347\272\247.kv" @@ -19,20 +19,23 @@ lib kvlang/spec/词法/逻辑位运算与优先级 { 分别为按位与、按位或、按位异或、左移、右移。 `&` 一符二用,靠位置区分(同 C):操作数之后为中缀**按位与**;表达式起始或运算符之后为一元前缀 -**取址**(见下「取址运算符 `&`」)。 +**绝对地址**(见下「绝对地址运算符 `&`」)。 -## 取址运算符 `&` +## 绝对地址运算符 `&` -一元前缀 `&loc` 求值为 `loc` 所在节点的绝对 KV 路径字符串,等价 `kv·abs(loc)`。操作数须为位置 -(location):帧内裸名、容器/成员链(`x`、`list·1`、`base·field`)。 +一元前缀 `&loc` 求值为指向 `loc` 所在节点的**指针**(ref=1 Ptr:head 的 langtype = 目标 kindexpr、 +body = 目标绝对路径),等价 `kv·abs(loc)`——故它是**绝对地址运算符**,不是 C 式取址(kvspace 无进程私有 +内存地址)。操作数须为位置(location):帧内裸名、容器/成员链(`x`、`list·1`、`base·field`)。 -产物是普通路径串,与指针惯例同型(可 `-> p` 存指针、`+ "·n"` 拼子节点、赋给 `next` 字段);与 -`*T` ref 标注互补——`&` 造路径,`*` 标注该路径所指目标的形态(见 [[ptr]])。 +产物是**指针值**(不是 `char` 路径串):可 `-> p` 存进 `*T` 变量、可 `p·field` 经指针访问成员;需要目 +标整值时用 `*p` 解引用。与 `*T` ref 标注互补——`&` 造指针,`*T` 标注该指针所指目标的形态(见 +[[ptr]])。 ``` list·1 -> x -&x -> p // p = x 的绝对路径串,等价 kv·abs(x) -p + "·next" -> q +&x -> p // p = 指向 x 的 Ptr(ref=1),等价 kv·abs(x) +*p -> q // 解引用:取 x 的整值 +p·field -> v // 经指针访问成员(自动解引用,见 [[ptr]]) ``` ## 优先级 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 30647a1a..ffc11c65 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" @@ -24,8 +24,8 @@ PC 落在 kvspace、帧根落在 kvspace,故执行现场可观测、可崩溃 ## 变量名即指针 **代码中变量的名字,本身就是该变量的指针**(一条 kvspace 路径)kvspace/kvlang是路径寻址,而不是64位寻址。指令槽里存的从来不是值,而是指针文 -本;求值恒经一次指针间接。`&x`(`≡ kv·abs(x)`)是取址语法糖,取到的是 kvspace 路径串,**不是**私有内 -存地址(见 [[运算符基础]])。指针有两种形态: +本;求值恒经一次指针间接。`&x`(`≡ kv·abs(x)`)是**绝对地址运算符**,产指向该节点的 Ptr(ref=1, +body=绝对路径),**不是** C 式取址的私有内存地址(见 [[运算符基础]])。指针有两种形态: | 形态 | 写法 | 语义 | 解析 | |------|------|------|------| 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 0f796b39..c62792a4 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" @@ -21,11 +21,13 @@ lib kvlang/spec/类型系统/文法与合法性 { 空 `[]` **等价** `[.]`(恰一维、任意长)——字符串标注 `[]char/<编码>` 即此形。一个 dims 内**至多一 个**变元量词(`?`/`*`/`+`),其余须为定长元(整数或 `.`)——保证匹配 O(n) 确定、无回溯(见 [[匹配语 义与变参]])。 -- **mapexpr** = `memitemkeylangtype·memitemvaluelangtype`——`·`(U+00B7 中点)连接**两条各自独立的 - langtype**:左侧是 item **键**类型、右侧是 item **值/body** 类型。值类型递归为完整类型表达式(故 - map 可无限嵌套)。map 声明形如 `memheadname:memitemkeylangtype·memitemvaluelangtype={}`,术语与形态 - 详见 [[map容器]]。 -- **memitemkey**(键类型,三选一,各自独立可校验): +- **mapexpr** = `memitemkey_langtype_formatter·memitemvalue_langtype`——`·`(U+00B7 中点)连接**两条各 + 自独立**的类型表达式:左侧是 item **键**的格式器、右侧是 item **值/body** 类型。值类型递归为完整类型 + 表达式(故 map 可无限嵌套)。map 声明形如 + `memheadname:memitemkey_langtype_formatter·memitemvalue_langtype={}`,术语与形态详见 [[map容器]]。 +- **memitemkey_langtype_formatter**(键侧格式器,三选一,各自独立可校验):key 只在**路径系统**里、无 + XValue body,故键侧描述的不是「值的类型」而是「把 key 值格式化成路径段字符串的格式器」——其输出即访问 + 键(见 [[map容器]]): - **裸标量** `scalar`——如 `int64`、`float64`、`bool`;`scalar` 限 `bool` 与十个定宽数字种类。 - **字符串键** `[]char/<编码>`——等价 Go `map[string]V`。 - **标量元组键** `[scalar,…]`——括号内是**种类名序列**(如 `[float64,float64]`),元素须全为标量。 @@ -51,6 +53,10 @@ lib kvlang/spec/类型系统/文法与合法性 { + 尾随种类**(`[2]float64`)是 shape 的 `dims`——1 维、长度 2 的 float64 数组(见 [[数组形态]])。二者 语义差别巨大(定长异构位置元组 vs 一维定长向量),layout 与 runtime **不得**将元组键与数组形状互相塌 缩或推断转换。 + +**形状不可作键**:`b:[2]int32·[]char/utf8` 非法——形状 `[2]int32` 是 value/body 的 langtype(描述连续 +打包的元素),而键无 body;表达「两个 int32 的 key」只能用元组键 `[int32,int32]`,其 formatter 产出 +`b·[1,2]`(见 [[map容器]])。 - **any** = 通配,匹配任意种类;是**唯一**简写。 - **structref** = 以 `/` 起始的原型路径(如 `/lib/Point`),作为 atom 标注结构类型(见 [[struct]])。 @@ -83,6 +89,7 @@ structref 放行——裸名已被隐式展开为 `/lib/`,正是靠「 | `char/utf8·int64` | `char/*` 只能作 `[]char/*` 字符串键,不可裸作键(裸键仅限标量 `scalar`,如 `int64·int64` 合法) | | `[]int32·int64` | map 字符串键的编码非 `char/*` | | `[.]·int64` | map 键含维度 | +| `[2]int32·int64` | 数组形状不可作键(键无 body;要表达两个 int32 的 key 用 `[int32,int32]`) | | `[foo,int32]·int64` | 元组键含非标量元素 | | 裸 `[]` / 裸 `[.]` | 无基种类 | | `[*,+]int64`、`[?,*]int64` | 一个 dims 含多于一个变元量词(`?`/`*`/`+`) | diff --git "a/stdlib/kvlang/spec/03-\347\261\273\345\236\213\347\263\273\347\273\237/14-map\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-map\345\256\271\345\231\250.kv" index 8ca2e4d2..e40004ae 100644 --- "a/stdlib/kvlang/spec/03-\347\261\273\345\236\213\347\263\273\347\273\237/14-map\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-map\345\256\271\345\231\250.kv" @@ -11,22 +11,37 @@ lib kvlang/spec/类型系统/map容器 { 一个 map 的 kvlang 代码形式: ``` -memheadname : memitemkeylangtype · memitemvaluelangtype = {} +memheadname : memitemkey_langtype_formatter · memitemvalue_langtype = {} ``` | 位置 | 名称 | 含义 | |------|------|------| | `:` 之前 | **memheadname** | map 的名字(头名,命名整族成员) | -| `:` 与 `·` 之间 | **memitemkeylangtype** | item **键**的 langtype(独立 langtype) | -| `·` 之后 | **memitemvaluelangtype** | item **值/body** 的 langtype(独立 langtype,可递归嵌套) | +| `:` 与 `·` 之间 | **memitemkey_langtype_formatter** | item **键**的 langtype——键侧是**格式器**(见下),不是值类型 | +| `·` 之后 | **memitemvalue_langtype** | item **值/body** 的 langtype(独立 langtype,可递归嵌套) | -`·`(U+00B7 中点)连接 item 的键类型与值类型两条**各自独立**的 langtype。**通过 item 的 key 访问 item -的 body**:写 `memheadname·` 即取到该 item 的 body(memitemvalue)。 +`·`(U+00B7 中点)连接 item 的键侧与值侧两条**各自独立**的类型表达式。**通过 item 的 key 访问 item 的 +body**:写 `memheadname·` 即取到该 item 的 body(memitemvalue)。 -**memitemkey** 是 key-eligible langtype,三选一:**裸标量**(`int64`)、**字符串键** -`[]char/<编码>`、**标量元组键** `[scalar,…]`。memitemkey 逐字落键——访问键就是 memitemkey 值按其 -langtype 的**字面量本身**,kvspace 与 kvlangruntime 均**不得**加壳、归一化或改键(逐字铁律与 -`[float64,float64]`(元组键)≠ `[2]float64`(数组形状)的区分见 [[文法与合法性]])。 +### 键侧是 formatter,不是值类型 + +**memitemkey_langtype_formatter**:memitemkey 侧不是「值的类型」,而是**把 key 值格式化成路径段字符串的 +格式器**——因为 memitemkey 永远活在**路径系统**里(`memhead·`),**从不进入任何 XValue 的 +body**。key 侧没有 body 可承载类型,key 的类型完全是字符串层面的事,故必须由 formatter 规定「什么值的 +key 格式化成什么字面量文本」: + +| memitemkey 类型 | formatter 输出(= 访问键) | 例 | +|-----------------|---------------------------|-----| +| 裸标量(`bool` + 十个定宽数字种类) | 该标量的字面量文本 | `b·200` | +| 标量元组 `[scalar,…]` | `[v0,v1,…]`(逗号分隔、无空格) | `a·[3.252,235124.23]` | +| `[]char/<编码>` | 字符串本身(裸名) | `m·a` / `kv·set(m,"a",v)` | + +**不得**用数组形状 `[N]T` / `[d0,d1]T` 作键:形状描述「一段连续打包进 body 的等宽元素」,属 **value 的 +langtype**;key 无 body、纯路径文本,形状对它没有意义。故 `b:[2]int32·[]char/utf8 = {}` 报错,而表达同 +样「两个 int32」的元组键 `b2:[int32,int32]·[]char/utf8 = {}` 合法(formatter 产出 `b2·[1,2]`)。 + +`a:int32·int32 = {}`(裸标量键,访问键 `a·200`)与 `a:[int32]·int32 = {}`(一元元组键,访问键 +`a·[200]`)是**两个不同的 formatter**,不得互相转换(逐字铁律见 [[文法与合法性]])。 ## 例子 @@ -41,6 +56,10 @@ b·200 = 7 // 访问键就是 200,禁止写成 b·[200] a:[float64,float64]·int32 = {} // 标量元组键 map([float64,float64] ≠ [2]float64) a·[342.124,23.2345] = 1 // 访问键就是元组字面量本身 + +b2:[int32,int32]·[]char/utf8 = {} // 元组键 + 字符串值(两元素都是标量,合法) +b2·[1,2] = "x" // 访问键 = formatter 输出 "[1,2]" +// b:[2]int32·[]char/utf8 = {} // 非法:数组形状 [2]int32 不是键(键无 body 可承载) ``` memitemvalue 可递归嵌套(`[]char/utf8·[]char/utf8·int64` 即 `map[string]map[string]int64`)。 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 1c33bf4f..cd944b4a 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" @@ -14,9 +14,10 @@ lib kvlang/spec/类型系统/成员访问 { 由 runtime-c 沿 Ptr 解引用取被指向值作键;省略 `*` 非法(不自动解引用)。这是**显式** deref、非自动改 键(运行期语义见 [[成员访问]](runtime 卷))。 -`base` 即 map 的 memheadname(或 struct 实例名)。访问键**逐字即 memitemkey 值**:kvspace 与 -kvlangruntime 均不得归一化、改写或自动加壳(详见 [[文法与合法性]] 的逐字铁律,术语见 [[map容器]])。裸 -标量键 `base·200` 与 1 元元组键 `base·[200]` 是**不同** memitemkey,不得互转。 +`base` 即 map 的 memheadname(或 struct 实例名)。访问键**逐字即键侧 formatter 的输出**(memitemkey 只 +在路径系统、无 body,见 [[map容器]]):kvspace 与 kvlangruntime 均不得归一化、改写或自动加壳(详见 +[[文法与合法性]] 的逐字铁律)。裸标量键 `base·200` 与 1 元元组键 `base·[200]` 是**不同** formatter, +不得互转。 容器成员一律走 `·`(或 `kv·get`/`kv·set`)作**索引**,**不得**用 `[]` 索引运算符;`[]` 只索引 compact 数组(见 [[数组形态]])。注意:元组键 `base·[…]` 里的 `[…]` 是 **memitemkey 值字面量**、不是索引运算 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 f61e6bb5..0e9a8ab1 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" @@ -13,7 +13,7 @@ lib kvlang/spec/类型系统/ptr { | 形态 | 语义 | |------|------| -| `&x` | 取地址 → ref=1 Ptr(`&x ≡ kv·abs(x)`,返回绝对路径串) | +| `&x` | **绝对地址** → ref=1 Ptr(`≡ kv·abs(x)`,body = 目标绝对路径) | | `p`(`*T` 变量读值) | 得地址值本身(不穿透) | | `*p` | 解引用 → 读 body 目标地址的值 | | `None` | **空指针**(唯一的空指针字面量;即键不存在=无值) | @@ -41,13 +41,13 @@ p·val -> v // 成员访问经指针自动解引用:读 /n1·val if (p != None) { … } // 空指针判定 ``` -`&` 对**裸名** `&x` 取帧槽地址(`≡ kv·abs(x)`)、对**成员链** `&t·2` 取成员路径地址(`≡ +`&` 对**裸名** `&x` 产帧槽的绝对地址(`≡ kv·abs(x)`)、对**成员链** `&t·2` 产成员路径的绝对地址(`≡ kv·abs(t, "2")`),均产 ref=1 Ptr、body 为目标 key 路径。 成员访问 `p·field` 经指针**自动解引用**(对齐 Go/Rust 的 `p.field`);需要「指针指向的整值」(如指针 指向标量)时用显式 `*p`。二者不冲突:`*p` 取整值、`p·field` 取成员。 -嵌套指针(`**T`)不在本模型内:wire 层 langtype 串不含 `*`、ref 仅单字节,无法表达层数。链表/树/取址 +嵌套指针(`**T`)不在本模型内:wire 层 langtype 串不含 `*`、ref 仅单字节,无法表达层数。链表/树/绝对地址 皆一层指针,已覆盖;C 里 `**` 的「out 参数传地址」由 kvlang 写参取代——要直写调用方对象就写 `-> (r:*T)`(地址写参),`-> (r:T)` 是值写参(copy-in / copy-out),无需 `**`。 "#### -> /lib/kvlang/spec/类型系统/ptr diff --git "a/stdlib/kvlang/spec/\350\256\276\350\256\241\347\220\206\347\224\261/02-\344\270\200\345\210\207\347\232\206\346\230\216\346\226\207.kv" "b/stdlib/kvlang/spec/\350\256\276\350\256\241\347\220\206\347\224\261/02-\344\270\200\345\210\207\347\232\206\346\230\216\346\226\207.kv" index eca8fa33..f05f1cd9 100644 --- "a/stdlib/kvlang/spec/\350\256\276\350\256\241\347\220\206\347\224\261/02-\344\270\200\345\210\207\347\232\206\346\230\216\346\226\207.kv" +++ "b/stdlib/kvlang/spec/\350\256\276\350\256\241\347\220\206\347\224\261/02-\344\270\200\345\210\207\347\232\206\346\230\216\346\226\207.kv" @@ -34,11 +34,12 @@ def rwir 路由)、读写哪个 slot。调度层的绝对耗时在 tensor 计 字符串 PC 直接带来崩溃恢复能力:进程崩溃后,PC 路径已持久化在 kvspace,重启后从该路径继续执行,无需 重放或检查点协议。整数 PC 做不到这点,因为整数脱离了进程上下文就失去意义。 -## 为什么 `&` 取的是路径而非私有地址 +## 为什么 `&` 是绝对地址运算符而非取址运算符 传统语言的 `&` 取址产生的是私有内存地址,只在当前进程内有意义,且与内存布局深度绑定。kvlang 的"变量 名"本身就是该变量的 kvspace 路径——路径在任何连接到同一 kvspace 的节点上都有意义。故 kvlang 保留 `&x` -(`≡ kv·abs(x)`),但它的产物是**路径指针**、不是私有地址:没有进程私有地址空间,也没有内存布局意义 -上的"取址"(见 [[寻址与命名]]、[[运算符基础]])。 +(`≡ kv·abs(x)`),但它的产物是**指向该节点的 Ptr**(ref=1,body=绝对路径)、不是私有地址:没有进程私 +有地址空间,也没有 C 式取址的内存布局含义,故规范称它为**绝对地址运算符**(见 [[寻址与命名]]、 +[[运算符基础]])。 "#### -> /lib/kvlang/spec/设计理由/一切皆明文 } diff --git "a/stdlib/kvlang/spec/\351\231\204\345\275\225/03-\347\261\273\345\236\213\350\241\250\350\276\276\345\274\217\346\226\207\346\263\225.kv" "b/stdlib/kvlang/spec/\351\231\204\345\275\225/03-\347\261\273\345\236\213\350\241\250\350\276\276\345\274\217\346\226\207\346\263\225.kv" index f5c5470d..7bbe88a0 100644 --- "a/stdlib/kvlang/spec/\351\231\204\345\275\225/03-\347\261\273\345\236\213\350\241\250\350\276\276\345\274\217\346\226\207\346\263\225.kv" +++ "b/stdlib/kvlang/spec/\351\231\204\345\275\225/03-\347\261\273\345\236\213\350\241\250\350\276\276\345\274\217\346\226\207\346\263\225.kv" @@ -12,11 +12,11 @@ type_expr = [ ref_prefix ] atom { "|" atom } (* ref 前缀可选;layout ref_prefix = "*" | "@" (* * → ref=1(kvspace 内间接);@ → ref=2(扩展世界,值在 kvspace 之外,runtime-c 不可直达、由支持 @ 的 rwir 兑现)。签名位置可写:`T` 值传、`*T` 址传、`@T` 扩展存储;值容器(map/struct)无值本体可拷,必须带 `*`/`@`,见 [[函数]] *) atom = shape | mapexpr | structref shape = [ dims ] ( any | kind ) -mapexpr = memitemkey "·" memitemvalue (* stringkeymap;`·` 连接两条独立 langtype:左=item 键类型、右=item 值类型。声明形如 memheadname:memitemkey·memitemvalue={},见 [[map容器]] *) +mapexpr = memitemkey "·" memitemvalue (* stringkeymap;`·` 左=item 键侧的**格式器**(memitemkey_langtype_formatter)、右=item 值类型。声明形如 memheadname:memitemkey_langtype_formatter·memitemvalue_langtype={},见 [[map容器]] *) memitemvalue = type_expr (* item 值/body 类型,递归为完整 type_expr,故 map 可无限嵌套 *) -memitemkey = scalar (* 裸标量键:访问键即该标量字面量本身,如 b·200;禁止包成 [200](见 [[文法与合法性]]) *) - | "[]" char_enc (* 字符串键,等价 Go map[string]V *) - | "[" scalar { "," scalar } "]" (* 标量元组键:括号内是种类名序列,访问键即括号元组字面量本身,如 a·[342.124,23.2345] *) +memitemkey = scalar (* 裸标量键:键只在路径系统、无 body,故这是"格式器"——输出该标量字面量本身,如 b·200;禁止包成 [200](见 [[文法与合法性]]) *) + | "[]" char_enc (* 字符串键(格式器输出裸名字符串),等价 Go map[string]V *) + | "[" scalar { "," scalar } "]" (* 标量元组键(格式器输出 `[v0,v1,…]`),如 a·[342.124,23.2345];与数组形状 [2]float64 不同——形状不可作键 *) structref = path (* struct 原型路径,如 /lib/Point *) char_enc = "char/utf8" | "char/utf32" | "char/ascii" scalar = "bool" diff --git "a/stdlib/kvlang/spec/\351\231\204\345\275\225/05-\350\241\250\350\276\276\345\274\217.kv" "b/stdlib/kvlang/spec/\351\231\204\345\275\225/05-\350\241\250\350\276\276\345\274\217.kv" index 4e360cff..348115e3 100644 --- "a/stdlib/kvlang/spec/\351\231\204\345\275\225/05-\350\241\250\350\276\276\345\274\217.kv" +++ "b/stdlib/kvlang/spec/\351\231\204\345\275\225/05-\350\241\250\350\276\276\345\274\217.kv" @@ -18,7 +18,7 @@ primary = literal | ident | path | struct_literal | map_literal -prefix_unary = "-" | "!" | "√" | "&" | "*" (* √ = sqrt(U+221A);&x ≡ kv·abs(x) 取址;*p 解引用 *) +prefix_unary = "-" | "!" | "√" | "&" | "*" (* √ = sqrt(U+221A);&x ≡ kv·abs(x) 绝对地址(产 ref=1 Ptr);*p 解引用 *) infix_primary = binary_op expr diff --git "a/stdlib/kvlang/spec/\351\231\204\345\275\225/07-\345\206\205\345\273\272\345\207\275\346\225\260.kv" "b/stdlib/kvlang/spec/\351\231\204\345\275\225/07-\345\206\205\345\273\272\345\207\275\346\225\260.kv" index 92473604..11ae4db7 100644 --- "a/stdlib/kvlang/spec/\351\231\204\345\275\225/07-\345\206\205\345\273\272\345\207\275\346\225\260.kv" +++ "b/stdlib/kvlang/spec/\351\231\204\345\275\225/07-\345\206\205\345\273\272\345\207\275\346\225\260.kv" @@ -32,7 +32,7 @@ builtin_call = ( "abs" | "neg" | "sign" | "pow" | "sqrt" | "exp" | "log" (* ÷ : 两侧 int → 整除(C 风格);任一侧 float → 浮除 *) (* s[i] 读返单字符字符串,越界返 "";s[i]="X" 单字符替换写回新串 *) (* + 作用在 string∧string → 拼接 *) -(* &x 是 kv·abs(x) 的语法糖(一元前缀取址,返回 x 的绝对路径串);与中缀按位与 a & b 靠位置区分 *) +(* &x ≡ kv·abs(x):一元前缀**绝对地址**运算符,产指向 x 的 Ptr(ref=1,body=绝对路径);与中缀按位与 a & b 靠位置区分 *) ``` "## -> /lib/kvlang/spec/附录/内建函数 }