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
14 changes: 10 additions & 4 deletions layout/src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,15 +109,21 @@ impl FuncSig {
self.params.iter().map(|p| p.name.clone()).collect()
}

/// 参数 kindexp 列表(读参在前、写参在后,源文法逐字节),落盘于 rwir/rwfunc body。
pub fn kindexp_list(&self) -> Vec<String> {
/// 参数 langtype 列表(读参在前、写参在后),落盘于 rwir/rwfunc body。
/// 末读参尾缀 `...` 是签名层变参标记:此处剥离,langtype 串保持纯净(变参落 dynamic 字节)。
pub fn langtype_list(&self) -> Vec<String> {
self.params
.iter()
.chain(self.returns.iter())
.map(|p| p.ty.clone())
.map(|p| p.ty.strip_suffix("...").unwrap_or(&p.ty).to_string())
.collect()
}

/// 末读参是否变参(源尾缀 `...`)→ 落成主槽 body 的 dynamic 字节。
pub fn dynamic(&self) -> bool {
self.params.last().is_some_and(|p| p.ty.ends_with("..."))
}

pub fn num_reads(&self) -> i32 {
self.params.len() as i32
}
Expand Down Expand Up @@ -185,7 +191,7 @@ impl RwirDecl {
#[derive(Clone)]
pub struct Field {
pub name: String,
pub ty: String, // kindexpr(字段类型)
pub ty: String, // langtype(字段类型)
pub default: Option<Expr>, // 默认值字面量(None = 未给)
}

Expand Down
16 changes: 8 additions & 8 deletions layout/src/capi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -183,12 +183,12 @@ pub extern "C" fn kvlangLayoutDump(
}
}

// ── kindexpr 解析 ABI ──────────────────────────────────────────────────
// kindexpr 语法唯一事实源在 layout(kindexpr.rs);解析能力导出为 C ABI,
// ── langtype 解析 ABI ──────────────────────────────────────────────────
// langtype 语法唯一事实源在 layout(langtype.rs);解析能力导出为 C ABI,
// 供 runtime 之外的消费方(扩展宿主 term/numpy/json、byteseek…)读取 XValue head 时
// 复用,杜绝各处手写 head 结构/解析造成的 ABI 漂移(#70 遗留的旧 kind[32] 结构即此类)。

/// kindexpr 解析结果(repr(C),内存布局 = i32,i32,[i32;8],i32,[u8;64])。
/// langtype 解析结果(repr(C),内存布局 = i32,i32,[i32;8],i32,[u8;64])。
#[repr(C)]
pub struct kvlangKindexpr {
pub ref_: i32, // 0=内联 1=指针(*) 2=扩展句柄(@)
Expand All @@ -198,18 +198,18 @@ pub struct kvlangKindexpr {
pub kind: [u8; 64], // base kind,NUL 终止(如 "float64"、"char/utf8"、"rwir|rwfunc")
}

/// 解析 XValue head 的 kindexpr 内容(NUL 终止串,含 */@ 前缀与 [dims])。
/// 解析 XValue head 的 langtype 内容(NUL 终止串,含 */@ 前缀与 [dims])。
/// 成功返回 0,失败(空指针/空串)返回 -1。
#[no_mangle]
pub extern "C" fn kvlangKindexprParse(kindexpr: *const c_char, out: *mut kvlangKindexpr) -> i32 {
if kindexpr.is_null() || out.is_null() {
pub extern "C" fn kvlangKindexprParse(langtype: *const c_char, out: *mut kvlangKindexpr) -> i32 {
if langtype.is_null() || out.is_null() {
return -1;
}
let s = cstr(kindexpr);
let s = cstr(langtype);
if s.is_empty() {
return -1;
}
let (dims, kind) = kvkind::parse_kindexpr(s);
let (dims, kind) = kvkind::parse_langtype(s);
let out = unsafe { &mut *out };
out.ref_ = 0;
out.ndim = dims.len() as i32;
Expand Down
9 changes: 5 additions & 4 deletions layout/src/code.rs
Original file line number Diff line number Diff line change
Expand Up @@ -390,12 +390,12 @@ pub fn write_func(kv: &mut Kv, pkg: &str, fn_: &mut Func) {

let nr = fn_.sig.num_reads();
let nw = fn_.sig.num_writes();
let param_types: Vec<String> = fn_.sig.kindexp_list();
let param_types: Vec<String> = fn_.sig.langtype_list();

let mut pairs: Vec<(String, Vec<u8>)> = Vec::new();
pairs.push((
format!("{func_dir}/[0,0]"),
kvkind::new_rwfunc(seq.len() as i32, nr, nw, &param_types),
kvkind::new_rwfunc(seq.len() as i32, nr, nw, fn_.sig.dynamic(), &param_types),
));
pairs.push((
keytree::lib_src(pkg, &fn_.sig.name),
Expand Down Expand Up @@ -465,7 +465,7 @@ pub fn write_struct_decl(kv: &mut Kv, decl: &StructDecl) {
/// 字段默认值 XValue:head kind = 字段类型,body = 默认字面量(未给则零值)。
/// 标量+char 直接编码;带 dims / structref 仅记录类型(空 body),嵌套 struct 待定。
fn field_default(ty: &str, default: Option<&Expr>) -> Vec<u8> {
let (dims, base) = kvkind::parse_kindexpr(ty);
let (dims, base) = kvkind::parse_langtype(ty);
let s = default.map(|e| e.val.clone()).unwrap_or_default();
if base.starts_with("char/") {
return ffi::new_char(&base, &s);
Expand Down Expand Up @@ -501,7 +501,8 @@ pub fn write_rwir_decl(kv: &mut Kv, decl: &RwirDecl) {
let v = kvkind::new_defrwir(
decl.sig.num_reads(),
decl.sig.num_writes(),
&decl.sig.kindexp_list().join("\n"),
decl.sig.dynamic(),
&decl.sig.langtype_list().join("\n"),
);
let _ = kv.set(&[(keytree::rwir(&opcode), v)]);
}
Expand Down
8 changes: 4 additions & 4 deletions layout/src/ffi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ extern "C" {
fn kvspaceDecodeHead(data: *const u8, data_len: u32, out: *mut kvspaceHead_t) -> c_int;

fn kvspaceNewPtr(
target_kindexpr: *const c_char,
target_langtype: *const c_char,
target: *const c_char,
out: *mut *mut u8,
out_len: *mut u32,
Expand Down Expand Up @@ -190,7 +190,7 @@ impl Kv {
Kv { h }
}

/// 写:pairs 的值为预编码 TLV;逐条解 head 取 (kindexpr, body),经 WriteNewPlace
/// 写:pairs 的值为预编码 TLV;逐条解 head 取 (langtype, body),经 WriteNewPlace
/// 向 kvspace 要 body 偏移指针后直接写入 body 字节(新建/换 kind/换尺寸唯一原语)。
pub fn set(&mut self, pairs: &[(String, Vec<u8>)]) -> Result<(), String> {
for (key, tlv) in pairs {
Expand Down Expand Up @@ -379,8 +379,8 @@ pub fn decode_head(data: &[u8]) -> kvspaceHead_t {

// ── 标准标量构造器 ───────────────────────────────────────────────────

pub fn new_ptr(target_kindexpr: &str, target: &str) -> Vec<u8> {
let ck = CString::new(target_kindexpr).expect("no NUL");
pub fn new_ptr(target_langtype: &str, target: &str) -> Vec<u8> {
let ck = CString::new(target_langtype).expect("no NUL");
let ct = CString::new(target).expect("no NUL");
call_codec(|out, out_len| unsafe { kvspaceNewPtr(ck.as_ptr(), ct.as_ptr(), out, out_len) })
}
Expand Down
68 changes: 39 additions & 29 deletions layout/src/kvkind.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@ pub fn head(data: &[u8]) -> ffi::kvspaceHead_t {
ffi::decode_head(data)
}

/// 解析 kindexpr 内容 → (dims, base kind)。kindexpr 无前缀(ref/ptr 归 head.ref)。
pub fn parse_kindexpr(kx: &str) -> (Vec<i32>, String) {
/// 解析 langtype 内容 → (dims, base kind)。langtype 无前缀(ref/ptr 归 head.ref)。
pub fn parse_langtype(kx: &str) -> (Vec<i32>, String) {
if kx.starts_with('[') {
match kx.find(']') {
Some(end) => (
Expand All @@ -57,8 +57,8 @@ pub fn parse_kindexpr(kx: &str) -> (Vec<i32>, String) {
}
}

/// 读 head 的 kindexpr 内容(去 NUL)。
pub fn kindexpr(data: &[u8]) -> String {
/// 读 head 的 langtype 内容(去 NUL)。
pub fn langtype(data: &[u8]) -> String {
if data.is_empty() {
return String::new();
}
Expand All @@ -75,7 +75,7 @@ pub fn kind(data: &[u8]) -> String {
if data.is_empty() {
return String::new();
}
parse_kindexpr(&kindexpr(data)).1
parse_langtype(&langtype(data)).1
}

pub fn is_ptr(data: &[u8]) -> bool {
Expand All @@ -86,7 +86,7 @@ pub fn array_len(data: &[u8]) -> i32 {
if data.is_empty() {
return 0;
}
let dims = parse_kindexpr(&kindexpr(data)).0;
let dims = parse_langtype(&langtype(data)).0;
if dims.is_empty() {
1
} else {
Expand All @@ -104,7 +104,7 @@ pub fn body<'a>(data: &'a [u8], h: &ffi::kvspaceHead_t) -> &'a [u8] {
&data[off..off + len]
}

/// 指针目标 key(Ptr 的 body 即目标 key 路径;head 去 * 为目标完整 kindexpr)。
/// 指针目标 key(Ptr 的 body 即目标 key 路径;head 去 * 为目标完整 langtype)。
pub fn ptr_target(data: &[u8]) -> String {
let h = ffi::decode_head(data);
String::from_utf8_lossy(body(data, &h)).into_owned()
Expand All @@ -122,7 +122,7 @@ pub fn display(data: &[u8]) -> String {
if data.is_empty() {
return "None".to_string();
}
let (_, k) = parse_kindexpr(&kindexpr(data));
let (_, k) = parse_langtype(&langtype(data));
if k.is_empty() {
return "None".to_string();
}
Expand Down Expand Up @@ -187,21 +187,23 @@ fn plain_value(k: &str, b: &[u8]) -> String {
.map(|c| char::from_u32(le_u32(c)).unwrap_or('\u{FFFD}'))
.collect(),
"index" => format!("({})", count_names(b)),
// kvlang 自有 kind:body = [2B nr][2B nw][sig];槽值/调用目标 nr=nw=0,取 sig 即可。
// kvlang 自有 kind:body = [2B nr][2B nw][1B dynamic][sig];槽值/调用目标 nr=nw=0,取 sig 即可。
"rwir" | "rwir|rwfunc" | "rwfunc" | "defrwir" => {
let (nr, nw) = if b.len() >= 4 {
let (nr, nw, dynamic) = if b.len() >= 5 {
(
u16::from_le_bytes([b[0], b[1]]),
u16::from_le_bytes([b[2], b[3]]),
b[4] != 0,
)
} else {
(0, 0)
(0, 0, false)
};
let sig = String::from_utf8_lossy(&b[4.min(b.len())..]).into_owned();
let sig = String::from_utf8_lossy(&b[5.min(b.len())..]).into_owned();
let var = if dynamic { "..." } else { "" };
if nr == 0 && nw == 0 {
sig
} else {
format!("(nr={nr},nw={nw}) {sig}")
format!("(nr={nr},nw={nw}{var}) {sig}")
}
}
_ => String::from_utf8_lossy(b).into_owned(),
Expand All @@ -214,34 +216,35 @@ pub fn is_char_kind(k: &str) -> bool {

// ── kvlang 自有 kind:rwir / defrwir ────────────────────────────────
//
// body = [2B nr LE][2B nw LE][sig],array_len=1。
// rwir=槽值(引用串/opcode),defrwir=定义(签名)。
// body = [2B nr LE][2B nw LE][1B dynamic][sig],array_len=1。
// rwir=槽值(引用串/opcode),defrwir=定义(签名)。dynamic=末读参变参(arity,非 langtype)。

fn rwir_body(nr: i32, nw: i32, sig: &str) -> Vec<u8> {
let mut raw = Vec::with_capacity(4 + sig.len());
fn rwir_body(nr: i32, nw: i32, dynamic: bool, sig: &str) -> Vec<u8> {
let mut raw = Vec::with_capacity(5 + sig.len());
raw.extend_from_slice(&(nr as u16).to_le_bytes());
raw.extend_from_slice(&(nw as u16).to_le_bytes());
raw.push(dynamic as u8);
raw.extend_from_slice(sig.as_bytes());
raw
}

pub fn new_rwir(nr: i32, nw: i32, sig: &str) -> Vec<u8> {
ffi::tlv_encode(KIND_RWIR, &rwir_body(nr, nw, sig), 1)
ffi::tlv_encode(KIND_RWIR, &rwir_body(nr, nw, false, sig), 1)
}

/// 调用目标(看起来像函数调用的 opcode)→ kindexpr `rwir|rwfunc` 并列。
/// 调用目标(看起来像函数调用的 opcode)→ langtype `rwir|rwfunc` 并列。
/// 静态无法判定是扩展 rwir 还是用户 rwfunc,交 runtime 查 /lib/<op> 的 XValue kind 分派。
pub fn new_rwir_union(sig: &str) -> Vec<u8> {
ffi::tlv_encode(KIND_RWIR_OR_RWFUNC, &rwir_body(0, 0, sig), 1)
ffi::tlv_encode(KIND_RWIR_OR_RWFUNC, &rwir_body(0, 0, false, sig), 1)
}

pub fn new_defrwir(nr: i32, nw: i32, sig: &str) -> Vec<u8> {
ffi::tlv_encode(KIND_DEF_RWIR, &rwir_body(nr, nw, sig), 1)
pub fn new_defrwir(nr: i32, nw: i32, dynamic: bool, sig: &str) -> Vec<u8> {
ffi::tlv_encode(KIND_DEF_RWIR, &rwir_body(nr, nw, dynamic, sig), 1)
}

// ── struct 原型(对齐 runtime kvlangBuiltinMemindex)─────────────────
//
// /lib/Name kind=struct,body="name:kindexpr\n..."(字段声明类型,供实例化类型校验)
// /lib/Name kind=struct,body="name:langtype\n..."(字段声明类型,供实例化类型校验)
// /lib/Name· kind=index,body=[4B count LE][name\n...](字段名唯一权威)

pub fn new_struct(fields: &[(String, String)]) -> Vec<u8> {
Expand All @@ -261,12 +264,19 @@ pub fn new_memindex(names: &[String]) -> Vec<u8> {

// ── kvlang 自有 kind:rwfunc ────────────────────────────────────────
//
// body = [2B nr LE][2B nw LE][param_types 以 \n 连接],array_len=num_insts。

pub fn new_rwfunc(num_insts: i32, nr: i32, nw: i32, param_types: &[String]) -> Vec<u8> {
let mut raw = Vec::with_capacity(4 + param_types.iter().map(|s| s.len()).sum::<usize>());
// body = [2B nr LE][2B nw LE][1B dynamic][param_types 以 \n 连接],array_len=num_insts。

pub fn new_rwfunc(
num_insts: i32,
nr: i32,
nw: i32,
dynamic: bool,
param_types: &[String],
) -> Vec<u8> {
let mut raw = Vec::with_capacity(5 + param_types.iter().map(|s| s.len()).sum::<usize>());
raw.extend_from_slice(&(nr as u16).to_le_bytes());
raw.extend_from_slice(&(nw as u16).to_le_bytes());
raw.push(dynamic as u8);
raw.extend_from_slice(param_types.join("\n").as_bytes());
ffi::tlv_encode(KIND_RWFUNC, &raw, num_insts)
}
Expand All @@ -287,10 +297,10 @@ pub fn rwfunc_num_writes(body: &[u8]) -> i32 {
}

pub fn rwfunc_param_types(body: &[u8]) -> Vec<String> {
if body.len() <= 4 {
if body.len() <= 5 {
return Vec::new();
}
String::from_utf8_lossy(&body[4..])
String::from_utf8_lossy(&body[5..])
.split('\n')
.map(|s| s.to_string())
.collect()
Expand Down
Loading
Loading