diff --git a/deps.json b/deps.json index 0f74cb07..1e4e1b5e 100644 --- a/deps.json +++ b/deps.json @@ -1,7 +1,7 @@ { - "kvspace": "v0.2.14", - "kvspace-c": "v0.2.14", - "kvspace-durable": "v0.2.14", + "kvspace": "v0.2.15", + "kvspace-c": "v0.2.15", + "kvspace-durable": "v0.2.15", "blockmalloc": "v0.1.4", "slotsboxmalloc": "v0.1.5" } diff --git a/extensions/kvlang/syntaxes/kvlang.tmLanguage.json b/extensions/kvlang/syntaxes/kvlang.tmLanguage.json index e0128181..076fb433 100644 --- a/extensions/kvlang/syntaxes/kvlang.tmLanguage.json +++ b/extensions/kvlang/syntaxes/kvlang.tmLanguage.json @@ -46,7 +46,7 @@ }, "keyword": { "name": "keyword.control.kvlang", - "match": "\\b(rwfunc|rwir|lib|if|else|for|while|break|continue|return)\\b" + "match": "\\b(rwfunc|rwir|lib|struct|if|else|for|while|break|continue|return)\\b" }, "block_label": { "name": "entity.name.label.kvlang", diff --git a/layout/src/code.rs b/layout/src/code.rs index 91796038..d3f91da0 100644 --- a/layout/src/code.rs +++ b/layout/src/code.rs @@ -1,17 +1,19 @@ //! layoutcode(对齐 layout/layout.go):检查 AST 并把结果布局写到 /lib/ 下的结构化 KV。 //! //! 存储约定: -//! /lib/·/[0,0] 布局后签名(kind=rwfunc) -//! /lib/·/ 命名参数→slot 指针(langtype=char, ref=1) +//! /lib/·/[0,0] 布局后签名锚点(kind=rwfunc,body=计数头 [nr,nw,dyn]) +//! /lib/·/ 命名参数→slot 指针(langtype=该参类型, ref=1, body=坐标) //! /lib/·/[i,j] 编译后指令(kind=rwir),i 从 1 开始 //! /lib/·/‥labels/ label → irseq -//! /lib/·.src 源码副本 +//! /lib/·.src 源码副本(仅 write_func 保留写入,dump 不再依赖) //! //! WriteBody: DFS-number insts (incl. ScopeStmt), emit [i,j], rewrite goto/br labels to irseq. +//! dump: 反向——严格读 /lib/ 子树重建 AST(签名读命名参数 Ptr、体读线性槽+‥labels), +//! 不读 .src、不依赖签名行 [0,x] 静态槽。 use std::collections::HashMap; -use super::ast::{Expr, Func, Instruction, RwirDecl, Stmt, StructDecl}; +use super::ast::{self, Expr, Func, FuncSig, Instruction, Param, RwirDecl, ScopeStmt, Stmt, StructDecl}; use super::ffi::Kv; use super::{builtin, ffi, keytree, kvkind, lower, parser}; @@ -173,15 +175,16 @@ pub fn dump(kv: &mut Kv, lib: &str) -> String { // prefix 本身就是函数目录:直接重建该函数(pkg/name 从路径反推)。 let base = prefix.trim_start_matches("/lib/"); let (fpkg, name) = func_identity("", base); - let src = kvkind::value_string(&kv.get_one(&format!("{prefix}.src"))); + let dir = format!("{prefix}/"); + let text = reconstruct(kv, &dir, &name); let mut slots = Vec::new(); - collect_slots(kv, &format!("{prefix}/"), &mut slots); + collect_slots(kv, &dir, &mut slots); funcs.push(DumpFunc { pkg: fpkg, name, - src, + text, slots, - dir: format!("{prefix}/"), + dir, }); } else { // 虚拟 pkg:func dir 以 prefix 为前缀(`/lib/foo` 匹配 `/lib/foo·*` 与 `/lib/foo/*`)。 @@ -210,11 +213,11 @@ pub fn dump(kv: &mut Kv, lib: &str) -> String { out } -/// 一个可运行函数:源码(.src)+ 原始槽位注释。 +/// 一个可运行函数:从 /lib 子树重建的源码 + 原始槽位注释。 struct DumpFunc { pkg: String, name: String, - src: String, + text: String, slots: Vec, dir: String, } @@ -262,13 +265,13 @@ fn collect_funcs( let mem_sub = format!("{prefix}{base}·"); if is_func_dir(kv, &dir_sub) { let (fpkg, name) = func_identity(pkg, &base); - let src = kvkind::value_string(&kv.get_one(&format!("{prefix}{base}.src"))); + let text = reconstruct(kv, &dir_sub, &name); let mut slots = Vec::new(); collect_slots(kv, &dir_sub, &mut slots); funcs.push(DumpFunc { pkg: fpkg, name, - src, + text, slots, dir: dir_sub, }); @@ -342,7 +345,7 @@ fn emit_node(out: &mut String, node: &DumpNode, indent: &str) { } fn emit_func(out: &mut String, f: &DumpFunc, indent: &str) { - for line in f.src.lines() { + for line in f.text.lines() { out.push_str(indent); out.push_str(line); out.push('\n'); @@ -360,6 +363,251 @@ fn emit_func(out: &mut String, f: &DumpFunc, indent: &str) { out.push('\n'); } +// ── dump 重建:严格从 /lib 子树反出可运行 kvlang(不读 .src)───────────── +// +// 数据来源(对齐 write_func / spec「指令布局格式」): +// 签名 ← [0,0] 计数头(nr,nw,dyn) + 命名参数 Ptr 键(langtype=类型、body=[0,±k] 定位读/写与序) +// 函数体 ← 线性指令槽 [n,0]=opcode、[n,-j]=读参、[n,j]=写参(n 连续、scope 已拍平) +// 控制流 ← ‥labels/