From 50cb74b592692bbf38da0b989bfb00e4bbaab73e Mon Sep 17 00:00:00 2001 From: "peng.li24" <734991033@qq.com> Date: Sat, 22 Aug 2026 06:25:13 +0000 Subject: [PATCH] =?UTF-8?q?feat:=20XValue=20head=20ro/vid=20=E5=90=8C?= =?UTF-8?q?=E6=AD=A5=EF=BC=88lower.rs/builtin.c=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude --- layout/src/lower.rs | 13 +++++++------ runtime/src/builtin.c | 18 ++++++++++-------- 2 files changed, 17 insertions(+), 14 deletions(-) diff --git a/layout/src/lower.rs b/layout/src/lower.rs index e2940642..47f43fc7 100644 --- a/layout/src/lower.rs +++ b/layout/src/lower.rs @@ -190,8 +190,8 @@ fn lower_for_with_cont( let len_slot = lg.tmp(); let keys_slot = lg.tmp(); let key_slot = lg.tmp(); - let is_map_obj = s.iter.op == "map" || s.iter.op == "obj" - || (s.iter.is_leaf() && matches!(tm.get(&s.iter.val), Some(t) if t == "obj" || t == "map")); + let is_obj = s.iter.op == "obj" + || (s.iter.is_leaf() && matches!(tm.get(&s.iter.val), Some(t) if t == "obj")); // 迭代源:裸标识符直接原地遍历;表达式(如数组字面量)先物化到临时槽。 let mut init_body = Vec::new(); @@ -214,7 +214,7 @@ fn lower_for_with_cont( slot }; init_body.push(make_copy_inst("-1", &idx_slot)); - if is_map_obj { + if is_obj { init_body.push(Stmt::Instruction(Instruction { comments: Vec::new(), expr: Some(ast::call("kv.list", vec![ast::leaf(&iter_slot)])), @@ -268,7 +268,7 @@ fn lower_for_with_cont( let body_lc = LoopCtx { break_label: exit_label.clone(), continue_label: cond_label.clone() }; let body_inner = lower_body(&s.body, lg, Some(&body_lc), tm); let mut body_insts = Vec::new(); - if is_map_obj { + if is_obj { body_insts.push(Stmt::Instruction(Instruction { comments: Vec::new(), expr: Some(ast::call("xv.at", vec![ast::leaf(&keys_slot), ast::leaf(&idx_slot)])), @@ -735,10 +735,11 @@ fn specialize_inst(inst: &mut Instruction, tm: &HashMap) { if e.is_leaf() { return; } - // xv.at/xv.set 基座是 obj/map → 降为 kv.get/kv.set(成员目录访问)。 + // xv.at/xv.set 基座是 obj → 降为 kv.get/kv.set(命名成员目录访问)。 + // map 是散 key 数组(base[i]),保持 xv.at/xv.set 走散 key 下标路径。 if (e.op == "xv.at" || e.op == "xv.set") && !e.args.is_empty() { if let Some(t) = tm.get(&e.args[0].val) { - if t == "obj" || t == "map" { + if t == "obj" { e.op = if e.op == "xv.at" { "kv.get".to_string() } else { "kv.set".to_string() }; } } diff --git a/runtime/src/builtin.c b/runtime/src/builtin.c index f5d0b93e..45f55fa4 100644 --- a/runtime/src/builtin.c +++ b/runtime/src/builtin.c @@ -1100,16 +1100,18 @@ int kvlangBuiltinMap(kvlangFrame_t *f) { char *fr = kvlangKeytreeFrameRoot(f->pc); for (int w = 0; w < f->inst->nw; w++) { char *ok = kvlangBuiltinResolveWriteSlot(f->kv, fr, f->inst->writes[w].name); - kvlangXvalue_t mark; kvlangXvalueNewTlv(&mark, KVSPACE_KIND_MAP, (const uint8_t *)"", 0, 1); - kvlangKvPair_t p0 = { ok, mark }; - char err[256]; kvlangKvSet(f->kv, &p0, 1, err, sizeof err); - kvlangXvalueFree(&mark); + /* 散 key 数组:base[i] 方括号下标,无根标记(对齐 array.scatter/separated_len)。 */ + int old = separated_len(f->kv, ok); + for (int i = 0; i < old; i++) { + kvlangStrbuf_t k; kvlangStrbufInit(&k); kvlangStrbufPrintf(&k, "%s[%d]", ok, i); + char err[256]; kvlangKvDel(f->kv, k.p, err, sizeof err); kvlangStrbufFree(&k); + } + char err[256]; kvlangKvDel(f->kv, ok, err, sizeof err); for (int i = 0; i < n; i++) { - char key[32]; snprintf(key, sizeof key, "[%d]", i); - char *mk = kvlangKeytreeMember(ok, key); - kvlangKvPair_t p = { mk, in[i] }; + kvlangStrbuf_t k; kvlangStrbufInit(&k); kvlangStrbufPrintf(&k, "%s[%d]", ok, i); + kvlangKvPair_t p = { k.p, in[i] }; kvlangKvSet(f->kv, &p, 1, err, sizeof err); - free(mk); + kvlangStrbufFree(&k); } free(ok); }