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
13 changes: 7 additions & 6 deletions layout/src/lower.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand All @@ -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)])),
Expand Down Expand Up @@ -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)])),
Expand Down Expand Up @@ -735,10 +735,11 @@ fn specialize_inst(inst: &mut Instruction, tm: &HashMap<String, String>) {
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() };
}
}
Expand Down
18 changes: 10 additions & 8 deletions runtime/src/builtin.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down
Loading