Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion benchmark/cases/binary_search/binary_search.kv
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ rwfunc bsearch(arr:*[int64]·int64, n:int64, target:int64) -> (idx:int64) {
while (lo <= hi) {
lo + hi -> s
s ÷ 2 -> mid
kv·get(arr, mid) -> mv
kvspace·get(arr, mid) -> mv
if (mv == target) {
mid -> idx
hi + 1 -> lo
Expand Down
10 changes: 5 additions & 5 deletions benchmark/cases/binary_trees/binary_trees.kv
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ rwfunc test() -> () {
top + 1 -> top
while (top > 0) {
top - 1 -> top
kv·get(bid, top) -> cur
kv·get(bdep, top) -> d
kvspace·get(bid, top) -> cur
kvspace·get(bdep, top) -> d
if (d > 0) {
nid + 1 -> nid
nid -> lc
Expand Down Expand Up @@ -50,10 +50,10 @@ rwfunc test() -> () {
tp + 1 -> tp
while (tp > 0) {
tp - 1 -> tp
kv·get(tid, tp) -> cur
kvspace·get(tid, tp) -> cur
count + 1 -> count
kv·get(L, cur) -> lc
kv·get(R, cur) -> rc
kvspace·get(L, cur) -> lc
kvspace·get(R, cur) -> rc
if (lc != 0) {
lc -> tid·*tp
tp + 1 -> tp
Expand Down
4 changes: 2 additions & 2 deletions benchmark/cases/hash_table/hash_table.kv
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,10 @@ rwfunc test() -> () {
while (i < n) {
i × 2654435761 -> k0
k0 % 100003 -> key
kv·get(h, key) != None -> ex
kvspace·get(h, key) != None -> ex
if (ex) {
hits + 1 -> hits
kv·get(h, key) -> v
kvspace·get(h, key) -> v
sum + v -> sum
}
i + 1 -> i
Expand Down
10 changes: 5 additions & 5 deletions benchmark/cases/k_nucleotide/k_nucleotide.kv
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ rwfunc test() -> () {
while (i < n) {
string·char(s, i) -> ch
string·ord(ch) -> c
kv·get(h, c) -> cur
kvspace·get(h, c) -> cur
if (cur == None) {
0 -> cur
}
Expand All @@ -27,10 +27,10 @@ rwfunc test() -> () {
i + 1 -> i
}
t1 = time·now()
kv·get(h, 65) -> a
kv·get(h, 67) -> cc
kv·get(h, 71) -> g
kv·get(h, 84) -> t
kvspace·get(h, 65) -> a
kvspace·get(h, 67) -> cc
kvspace·get(h, 71) -> g
kvspace·get(h, 84) -> t
println("knuc: A =", a, "C =", cc, "G =", g, "T =", t)
delta = time·sub(t1, t0)
ns = time/duration·as_nanos(delta)
Expand Down
2 changes: 1 addition & 1 deletion error_cases/index_error/at_oob.kv
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@
// error: KeyError: kv·at: key not found

rwfunc test() -> () {
kv·get([1, 2], 5) -> _
kvspace·get([1, 2], 5) -> _
}
2 changes: 1 addition & 1 deletion error_cases/index_error/typed_array_string_key.kv
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@

rwfunc test() -> () {
arr:[]int32 = [1, 2, 3]
kv·get(arr, "key") -> _
kvspace·get(arr, "key") -> _
}
2 changes: 1 addition & 1 deletion error_cases/key_error/kv_at_missing.kv
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@
// error: KeyError: kv·at: key not found

rwfunc test() -> () {
kv·get("/x", "y") -> _
kvspace·get("/x", "y") -> _
}
22 changes: 11 additions & 11 deletions layout/src/lower.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ fn is_container_type(t: &str) -> bool {
t == "stringkeymap" || t.contains(keytree::MEMBER_SEP)
}

/// `[]` 下标校验:xv·at/xv·set 基座若为容器类型 → 报错,逼用 kv·get/kv·set/`base·key`。
/// `[]` 下标校验:xv·at/xv·set 基座若为容器类型 → 报错,逼用 kvspace·get/kvspace·set/`base·key`。
fn is_container_ty(ty: &str) -> bool {
// 剥掉间接性前缀 `*`/`@` 再判:签名里 `p:*Point`、`m:*[int64]·int64` 的 `*` 是传递方式,
// 类型本体仍是值容器——不剥会把这类参数误判为"未定义容器",成员写全部被拒。
Expand Down Expand Up @@ -185,9 +185,9 @@ fn check_map_inst(s: &Instruction, defined: &HashSet<String>, diags: &mut Vec<Di
}
}
}
// kv·set(base, key, val) 成员形
// kvspace·set(base, key, val) 成员形
if let Some(e) = &s.expr {
if e.op == "kv·set" && e.args.len() >= 3 && !e.args[0].val.contains('/') {
if e.op == "kvspace·set" && e.args.len() >= 3 && !e.args[0].val.contains('/') {
check_map_base(&e.args[0].val, defined, Pos { line: 0, col: 0 }, diags);
}
}
Expand Down Expand Up @@ -243,7 +243,7 @@ fn check_subscript_expr(e: &Expr, tm: &HashMap<String, String>, diags: &mut Vec<
diags.push(Diagnostic {
pos: Pos { line: 0, col: 0 },
message: format!(
"`[]` 下标不能用于容器 `{}`(类型 {});容器成员访问用 kv·get/kv·set 或 `{}·key`,`[]` 仅限 compact array",
"`[]` 下标不能用于容器 `{}`(类型 {});容器成员访问用 kvspace·get/kvspace·set 或 `{}·key`,`[]` 仅限 compact array",
base.val, t, base.val
),
warn: false,
Expand Down Expand Up @@ -558,7 +558,7 @@ fn lower_for_with_cont(
let cond_slot = lg.tmp();
let len_slot = lg.tmp();
let key_slot = lg.tmp();
// 容器源(stringkeymap/struct)用 kv·listlen/kv·listn/kv·get 遍历,compact 数组源用
// 容器源(stringkeymap/struct)用 kvspace·listlen/kvspace·listn/kvspace·get 遍历,compact 数组源用
// ndarray·numel/xv·at(见 spec 控制流脱糖)。判据看**声明的类型**:map 的 kindexpr 恒含
// `key·value` 的那个 `·`(`[int64]·int64`、`[]char/utf8·int64`),compact 数组不含。
let is_obj = s.iter.op == "obj"
Expand Down Expand Up @@ -592,7 +592,7 @@ fn lower_for_with_cont(
if is_obj {
init_body.push(Stmt::Instruction(Instruction {
comments: Vec::new(),
expr: Some(ast::call("kv·listlen", vec![ast::leaf(&iter_slot)])),
expr: Some(ast::call("kvspace·listlen", vec![ast::leaf(&iter_slot)])),
writes: vec![len_slot.clone()],
write_types: Vec::new(),
arrow_left: false,
Expand Down Expand Up @@ -641,7 +641,7 @@ fn lower_for_with_cont(
body_insts.push(Stmt::Instruction(Instruction {
comments: Vec::new(),
expr: Some(ast::call(
"kv·listn",
"kvspace·listn",
vec![ast::leaf(&iter_slot), ast::leaf(&idx_slot)],
)),
writes: vec![key_slot.clone()],
Expand All @@ -651,7 +651,7 @@ fn lower_for_with_cont(
body_insts.push(Stmt::Instruction(Instruction {
comments: Vec::new(),
expr: Some(ast::call(
"kv·get",
"kvspace·get",
vec![ast::leaf(&iter_slot), ast::leaf(&key_slot)],
)),
writes: vec![s.var.clone()],
Expand Down Expand Up @@ -1043,19 +1043,19 @@ fn infer_op_type(opcode: &str, reads: &[String], tm: &mut HashMap<String, String
if opcode == "map" {
return "[]stringkeymap".to_string();
}
if opcode == "kv·set" {
if opcode == "kvspace·set" {
// 成员写的 base 类型**不在此推断**:map 必须显式声明准确类型
// (`m:[]char/utf8·int64 = {}`),由 check_map_defined 静态拦截未定义者。
return String::new();
}
match opcode {
"kvlen" | "ndarray·numel" | "ndarray·dim" | "kv·listlen" | "string·len" | "string·ord"
"kvlen" | "ndarray·numel" | "ndarray·dim" | "kvspace·listlen" | "string·len" | "string·ord"
| "string·cmp" | "string·find" | "string·parseint" | "xv·bodylen" => {
return "int64".to_string();
}
"xv·langtype" => return "[]char/utf8".to_string(),
"ndarray·shape" => return "[]int64".to_string(),
"kv·list" => return "[]char/utf8".to_string(),
"kvspace·list" => return "[]char/utf8".to_string(),
"string·char" | "string·set" | "string·slice" | "string·concat" | "string·formatint"
| "string·formatuint" => return "char/utf32".to_string(),
"random.int63" => return "int64".to_string(),
Expand Down
48 changes: 24 additions & 24 deletions layout/src/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -804,11 +804,11 @@ impl Parser {
bad(p, w, fname);
}
}
// kv.set 成员形(3 读:base, key, val)改写 base 的成员目录,命中读参**或别名**即拒绝。
// kvspace·set 成员形(3 读:base, key, val)改写 base 的成员目录,命中读参**或别名**即拒绝。
// 被写的参数**必须**声明在写参侧(签名诚实原则)——要就地改调用方的对象,
// 就把该参数写到 `-> (p:Point)` 里,而不是留在读参侧靠别名绕。
if let Some(e) = &inst.expr {
if e.op == "kv·set" && e.args.len() >= 3 {
if e.op == "kvspace·set" && e.args.len() >= 3 {
let base = &e.args[0].val;
if !base.contains('/') && (ro.contains(base) || tainted.contains_key(base)) {
if ro.contains(base) {
Expand Down Expand Up @@ -1274,8 +1274,8 @@ impl Parser {

fn parse_pratt(&mut self, min_prec: i32) -> Option<Expr> {
let mut left = self.parse_primary_expr()?;
// 成员链:base + 各段收集成单个变参 kv·get(base, seg1, seg2, ...),runtime 直接拼路径。
// 不在 layout 摊成嵌套 kv·get(内层返回的是值,丢路径,#110)。每段为静态字面量或
// 成员链:base + 各段收集成单个变参 kvspace·get(base, seg1, seg2, ...),runtime 直接拼路径。
// 不在 layout 摊成嵌套 kvspace·get(内层返回的是值,丢路径,#110)。每段为静态字面量或
// 动态键(*k 的变量)。
let mut chain_base: Option<Expr> = None;
let mut chain_segs: Vec<Expr> = Vec::new();
Expand Down Expand Up @@ -1327,11 +1327,11 @@ impl Parser {
continue;
}
}
// 成员链被打断(下标/中缀/循环尾):flush 成单个变参 kv·get。
// 成员链被打断(下标/中缀/循环尾):flush 成单个变参 kvspace·get。
if let Some(base) = chain_base.take() {
let mut args = vec![base];
args.append(&mut chain_segs);
left = ast::call("kv·get", args);
left = ast::call("kvspace·get", args);
}
// 后缀索引
if self.peek().kind == Kind::LBrack {
Expand All @@ -1349,8 +1349,8 @@ impl Parser {
let is_path = left.is_leaf() && left.val.starts_with('/');
let mut args = vec![left];
args.extend(indices);
// 路径字面量 + [idx] → kv.get(KV 路径成员访问);否则 xv.at(compact 数组元素)。
left = ast::call(if is_path { "kv·get" } else { "xv·at" }, args);
// 路径字面量 + [idx] → kvspace·get(KV 路径成员访问);否则 xv.at(compact 数组元素)。
left = ast::call(if is_path { "kvspace·get" } else { "xv·at" }, args);
continue;
}
let t = self.peek();
Expand All @@ -1368,7 +1368,7 @@ impl Parser {
if let Some(base) = chain_base.take() {
let mut args = vec![base];
args.append(&mut chain_segs);
left = ast::call("kv·get", args);
left = ast::call("kvspace·get", args);
}
Some(left)
}
Expand Down Expand Up @@ -1407,12 +1407,12 @@ impl Parser {
if symbol::lookup(&t.value).word == "add" {
return self.parse_pratt(UNARY_PREC);
}
// 一元前缀 & = 取址:&x ≡ kv·abs(x)(中缀 & 仍为按位与,走 pratt 中缀路径)。
// & 对成员链 kv·get(base, segs...) → kv·abs(base, segs...):取成员路径地址,非读值取址。
// 一元前缀 & = 取址:&x ≡ kvlang·abs(x)(中缀 & 仍为按位与,走 pratt 中缀路径)。
// & 对成员链 kvspace·get(base, segs...) → kvlang·abs(base, segs...):取成员路径地址,非读值取址。
if symbol::lookup(&t.value).word == "bitand" {
let arg = self.parse_pratt(UNARY_PREC)?;
let op = format!("kv{}abs", keytree::MEMBER_SEP);
let get = format!("kv{}get", keytree::MEMBER_SEP);
let op = format!("kvlang{}abs", keytree::MEMBER_SEP);
let get = format!("kvspace{}get", keytree::MEMBER_SEP);
if arg.op == get && arg.args.len() >= 2 {
return Some(ast::call(&op, arg.args));
}
Expand Down Expand Up @@ -1897,7 +1897,7 @@ impl Parser {
if (t.kind == Kind::Ident || is_path_literal) && self.peek_at(1).kind == Kind::Dot {
let mut w = self.advance().value;
// 成员链写槽:整段 p·obj·deep 收成单个 write 槽,交给 desugar_member_write
// 拆成 kv·set(base, "obj·deep", v)。勿在每段 · 处截断(否则 deep 被当独立写槽)。
// 拆成 kvspace·set(base, "obj·deep", v)。勿在每段 · 处截断(否则 deep 被当独立写槽)。
while self.peek().kind == Kind::Dot {
self.advance(); // .
w.push_str(keytree::MEMBER_SEP);
Expand Down Expand Up @@ -2054,7 +2054,7 @@ impl Parser {
}

// 下标写脱糖:arr[i,j] 写槽 + 值 e → xv·set(arr, i, j, e) -> arr(compact 数组,
// 读侧 arr[i,j]→xv·at 的对称)。arr· 前缀坐标或 / 路径 → kv·set。左右箭头共用:
// 读侧 arr[i,j]→xv·at 的对称)。arr· 前缀坐标或 / 路径 → kvspace·set。左右箭头共用:
// = 时 e 是 pratt 右值,-> 时 e 是箭头左值,语义一致。layout 不判维数,交给 runtime。
fn desugar_subscript_write(&mut self, inst: &mut Instruction) {
if inst.writes.len() != 1 || !inst.writes[0].contains('[') {
Expand All @@ -2068,7 +2068,7 @@ impl Parser {
let dot_coord = arr.ends_with(keytree::MEMBER_SEP);
let arr = arr.trim_end_matches(keytree::MEMBER_SEP).to_string();
let op = if dot_coord || arr.starts_with('/') {
"kv·set"
"kvspace·set"
} else {
"xv·set"
};
Expand Down Expand Up @@ -2101,13 +2101,13 @@ impl Parser {
}
let s = inst.writes[0].clone();
// 路径字面量(/ 开头)是完整 key,不是成员写,勿脱糖——**但含动态键段 `·*k` 的除外**:
// 那时 `·` 之后是运行期求值的段,必须脱糖成 kv·set(base, k, v) 才能取到 k 的值
// 那时 `·` 之后是运行期求值的段,必须脱糖成 kvspace·set(base, k, v) 才能取到 k 的值
// (否则会被当成字面 key `/tmp/ts·*k` 整段写下去)。
if s.starts_with('/') && !s.contains(&format!("{}*", keytree::MEMBER_SEP)) {
return;
}
// struct 赋值(RHS = struct·new):浅拷 base+一层成员,lower 为 kv·cplist(struct·new→temp, dst)。
// 不走 kv·set —— 后者只搬基值,struct 的成员会丢在临时槽。dst 传完整成员槽串,
// struct 赋值(RHS = struct·new):浅拷 base+一层成员,lower 为 kvspace·cplist(struct·new→temp, dst)。
// 不走 kvspace·set —— 后者只搬基值,struct 的成员会丢在临时槽。dst 传完整成员槽串,
// runtime ResolveWriteSlot 拼 <frame>+"base·key…" 即成员绝对路径。
let is_struct_new = inst
.expr
Expand All @@ -2116,13 +2116,13 @@ impl Parser {
.unwrap_or(false);
if is_struct_new && !s.contains('*') {
let e = inst.expr.take().unwrap();
inst.expr = Some(ast::call("kv·cplist", vec![e, ast::leaf(&s)]));
inst.expr = Some(ast::call("kvspace·cplist", vec![e, ast::leaf(&s)]));
inst.writes = Vec::new();
inst.write_types = Vec::new();
return;
}
// 成员链写槽 p·a·b = v → 变参 kv·set(p, "a", "b", v),与读侧 #110 一致逐段拼路径。
// 不再按首个 · 压扁成 kv·set(p, "a·b", v):扁平段把「成员链」与「含 · 的成员名」混为一谈。
// 成员链写槽 p·a·b = v → 变参 kvspace·set(p, "a", "b", v),与读侧 #110 一致逐段拼路径。
// 不再按首个 · 压扁成 kvspace·set(p, "a·b", v):扁平段把「成员链」与「含 · 的成员名」混为一谈。
let mut parts = s.split(keytree::MEMBER_SEP);
let base = parts.next().unwrap_or("").to_string();
let mut args = vec![ast::leaf(&base)];
Expand All @@ -2148,8 +2148,8 @@ impl Parser {
}
let e = inst.expr.take();
args.push(e.unwrap_or(ast::leaf("")));
// base.a.b = v 脱糖为 kv·set(base, "a", "b", v):kv·set 是 void(副作用写成员),无写槽
inst.expr = Some(ast::call("kv·set", args));
// base.a.b = v 脱糖为 kvspace·set(base, "a", "b", v):kvspace·set 是 void(副作用写成员),无写槽
inst.expr = Some(ast::call("kvspace·set", args));
inst.writes = Vec::new();
inst.write_types = Vec::new();
}
Expand Down
2 changes: 1 addition & 1 deletion layout/src/scanner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -464,7 +464,7 @@ pub fn scan(src: &str) -> Vec<Token> {
// ·(U+00B7)与 .(释放给小数 key)是路径字符;· 后的坐标段 [0,1] 是成员链。
if src[i] == 0xC2 && i + 1 < src.len() && src[i + 1] == 0xB7 {
// `·*`(动态成员名)不并入路径:让 `·`/`*`/`k` 单独成 token,交成员链解析
// 成 `kv·get/kv·set(base, k)`。`·` 后接名字的情况(`/lib/json·to` 的
// 成 `kvspace·get/kvspace·set(base, k)`。`·` 后接名字的情况(`/lib/json·to` 的
// 包·函数分隔符、`/tmp/ts·5` 的静态成员)仍按原样整段吃进路径 token。
if i + 2 < src.len() && src[i + 2] == b'*' {
break;
Expand Down
2 changes: 1 addition & 1 deletion runtime-rs/build.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// 链接 stock 三方 .so(camelCase,符合 deepx-design/doc/abi-naming-standard.md):
// kvlang_runtime —— 模式2 主导执行 + rwirext 宿主 ABI(kvlang/bin 新构建优先,回落 /usr/lib)
// kvspace —— dispatch 前端,按 DSN 运行时选后端(/usr/lib)
// kvlanglayout —— .kv 编译入库(kvlanglayout·* rwir + 启动 layout stdlib 用,/usr/lib)
// kvlanglayout —— .kv 编译入库(kvlang·* rwir + 启动 layout stdlib 用,/usr/lib)
// 并把 stdlib/**/*.kv(顶层语言级标准库)全部 include_str! 进二进制(EMBEDDED_KV),启动时 layout 进 kvspace。
use std::path::{Path, PathBuf};

Expand Down
2 changes: 1 addition & 1 deletion runtime-rs/src/engine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,7 @@ impl Engine {
}
}

/// 写一个字符串列表容器(供 fs·list 等返回可 for-in 的字符串列表,对齐 C kv·list 表示):
/// 写一个字符串列表容器(供 fs·list 等返回可 for-in 的字符串列表,对齐 C kvspace·list 表示):
/// dst = 容器值:langtype=`[int64]·[]char/utf32`(见 [[map容器]]),body 空,dims=[n]
/// dst· = memindex:kind=index,body=[4B count LE]["[0]\n[1]\n..."](成员坐标名唯一权威)
/// dst·[i] = 各成员字符串(char/utf32)
Expand Down
10 changes: 5 additions & 5 deletions runtime-rs/src/rwir/kvlanglayout.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
//! rwir `kvlanglayout·*`:自造 kv 代码入库/导出(直连 layout 的 C ABI)。
//! kvlanglayout·vet(src) -> "ok" | 错误信息 只校验(parse+lower),不写 kvspace
//! kvlanglayout·format(src) -> 规范化源码 | "error: …" 格式化(parse→规范化),不写 kvspace
//! kvlanglayout·layout(src) -> entry | "error: …" 把内存源码 layout 进 kvspace
//! kvlanglayout·dump(lib) -> dump 文本 | "error: …" 把 /lib 子树重构为可运行 kvlang 源码
//! rwir `kvlang·*`:自造 kv 代码入库/导出(直连 layout 的 C ABI)。
//! kvlang·vet(src) -> "ok" | 错误信息 只校验(parse+lower),不写 kvspace
//! kvlang·format(src) -> 规范化源码 | "error: …" 格式化(parse→规范化),不写 kvspace
//! kvlang·layout(src) -> entry | "error: …" 把内存源码 layout 进 kvspace
//! kvlang·dump(lib) -> dump 文本 | "error: …" 把 /lib 子树重构为可运行 kvlang 源码
//! 四者都在 C 边界 catch_unwind:坏代码返回 -1,绝不打崩宿主进程。

use std::ffi::c_char;
Expand Down
Loading
Loading