diff --git a/layout/src/kvkind.rs b/layout/src/kvkind.rs index 65b4aa47..10fd58b2 100644 --- a/layout/src/kvkind.rs +++ b/layout/src/kvkind.rs @@ -14,8 +14,8 @@ pub const KIND_CHAR_ASCII: &str = "char/ascii"; pub const KIND_BOOL: &str = "bool"; pub const KIND_INT64: &str = "int64"; pub const KIND_FLOAT64: &str = "float64"; -pub const KIND_OBJ: &str = "obj"; -pub const KIND_MAP: &str = "map"; +pub const KIND_OBJ: &str = "objindex"; +pub const KIND_MAP: &str = "strkeymapindex"; pub const KIND_INDEX: &str = "index"; pub const KIND_EXT_INDEX: &str = "extindex"; diff --git a/layout/src/lower.rs b/layout/src/lower.rs index 47f43fc7..4fc2ed8f 100644 --- a/layout/src/lower.rs +++ b/layout/src/lower.rs @@ -191,7 +191,7 @@ fn lower_for_with_cont( let keys_slot = lg.tmp(); let key_slot = lg.tmp(); let is_obj = s.iter.op == "obj" - || (s.iter.is_leaf() && matches!(tm.get(&s.iter.val), Some(t) if t == "obj")); + || (s.iter.is_leaf() && matches!(tm.get(&s.iter.val), Some(t) if t == "objindex")); // 迭代源:裸标识符直接原地遍历;表达式(如数组字面量)先物化到临时槽。 let mut init_body = Vec::new(); @@ -538,7 +538,7 @@ fn infer_inst(inst: &Instruction, tm: &mut HashMap) { }; // kv.set 成员形(3 读:base, key, val)是 void 无写槽,但 base 仍须推断为 obj/map(供 for-in / 成员访问) if e.op == "kv.set" && e.args.len() >= 3 && !e.args[0].val.contains('/') { - tm.entry(e.args[0].val.clone()).or_insert_with(|| "obj".to_string()); + tm.entry(e.args[0].val.clone()).or_insert_with(|| "objindex".to_string()); } if inst.writes.is_empty() { return; @@ -605,15 +605,15 @@ fn infer_op_type(opcode: &str, reads: &[String], tm: &mut HashMap= 3 { - tm.entry(reads[0].clone()).or_insert_with(|| "obj".to_string()); + tm.entry(reads[0].clone()).or_insert_with(|| "objindex".to_string()); } return String::new(); } @@ -739,7 +739,7 @@ fn specialize_inst(inst: &mut Instruction, tm: &HashMap) { // 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" { + if t == "objindex" { e.op = if e.op == "xv.at" { "kv.get".to_string() } else { "kv.set".to_string() }; } } diff --git a/layout/src/parser.rs b/layout/src/parser.rs index 5fed5543..6fbe4921 100644 --- a/layout/src/parser.rs +++ b/layout/src/parser.rs @@ -961,7 +961,7 @@ impl Parser { && self.peek_at(j + 1).value == "="); if !is_dict { // 值列表 `{v0, v1, ...}`(无 `=> =`)→ 散 key 数组字面量,区别于 dict 的 - // `key => = val`。散 key:每个元素落在 base. 独立 key(变长/可增长), + // `key => = val`。散 key:每个元素落在 base.i 独立 key(变长/可增长), // 字符串数组走这里;compact 定长打包走 `[...]`。 self.advance(); // consume { let mut elems = Vec::new(); diff --git a/layout/src/type_expr.rs b/layout/src/type_expr.rs index adb9aa00..0e2f4b40 100644 --- a/layout/src/type_expr.rs +++ b/layout/src/type_expr.rs @@ -15,8 +15,9 @@ fn known_kind(k: &str) -> bool { matches!( k, "bool" | "int8" | "int16" | "int32" | "int64" | "uint8" | "uint16" | "uint32" | "uint64" - | "float32" | "float64" | "char/utf32" | "char/utf8" | "char/ascii" | "obj" | "index" - | "extindex" | "rwir" | "rwfunc" | "scope" | "time" | "duration" + | "float32" | "float64" | "char/utf32" | "char/utf8" | "char/ascii" | "objindex" + | "strkeymapindex" | "index" | "extindex" | "rwir" | "rwfunc" | "scope" | "time" + | "duration" | "json" ) } @@ -131,11 +132,11 @@ mod tests { fn valid() { for e in [ "int64", "uint8", "float32", "bool", "any", - "char/utf8", "char/utf32", "char/ascii", "obj", "index", + "char/utf8", "char/utf32", "char/ascii", "objindex", "strkeymapindex", "json", "index", "[]float32", "[2]float32", "[2,3]float32", "[2,3,4]float64", "[?,768]float32", "[?,?]int8", "int64|float64", "[2,3]float32|float32", "[]float32|[]float64", - "bool|char/utf8", "index|obj", + "bool|char/utf8", "index|objindex", "json|strkeymapindex", "any...", "int64|float64...", "[]float32...", ] { assert!(valid_type_expr(e), "{e} should be valid"); @@ -170,7 +171,7 @@ mod tests { let cases = [ ("int64", "int64", 0, &[][..], true), ("int64", "float64", 0, &[], false), - ("any", "obj", 0, &[], true), + ("any", "objindex", 0, &[], true), ("any", "int4", 0, &[], true), ("char/utf8", "char/utf8", 0, &[], true), ("char/utf8", "char/utf32", 0, &[], false), @@ -185,7 +186,7 @@ mod tests { ("[2,3]float32|float32", "float64", 0, &[], false), ("[]float32|[]float64", "float64", 1, &[10], true), ("bool|char/utf8", "char/utf8", 0, &[], true), - ("index|obj", "index", 0, &[], true), + ("index|objindex", "index", 0, &[], true), ]; for (expr, kind, ndim, dims, want) in cases { let got = match_type(expr, kind, ndim, dims); diff --git a/runtime/src/const.h b/runtime/src/const.h new file mode 100644 index 00000000..196551c5 --- /dev/null +++ b/runtime/src/const.h @@ -0,0 +1,40 @@ +#pragma once + +/* ── 字符串常量唯一定义处(对齐 kvspace-durable/src/const.rs)────────── + * kind 常量 + 路径/成员分隔符。C 源码一律引用此处,禁止硬编码裸字符串。 */ + +/* ── XValueHead kind ───────────────────────────────────────────────── */ + +#define KVSPACE_KIND_NONE "None" +#define KVSPACE_KIND_BOOL "bool" +#define KVSPACE_KIND_INT8 "int8" +#define KVSPACE_KIND_INT16 "int16" +#define KVSPACE_KIND_INT32 "int32" +#define KVSPACE_KIND_INT64 "int64" +#define KVSPACE_KIND_UINT8 "uint8" +#define KVSPACE_KIND_UINT16 "uint16" +#define KVSPACE_KIND_UINT32 "uint32" +#define KVSPACE_KIND_UINT64 "uint64" +#define KVSPACE_KIND_FLOAT32 "float32" +#define KVSPACE_KIND_FLOAT64 "float64" +#define KVSPACE_KIND_CHAR "char/utf32" +#define KVSPACE_KIND_CHAR_UTF8 "char/utf8" +#define KVSPACE_KIND_CHAR_ASCII "char/ascii" +#define KVSPACE_KIND_OBJ "objindex" +#define KVSPACE_KIND_MAP "strkeymapindex" +#define KVSPACE_KIND_INDEX "index" +#define KVSPACE_KIND_EXT_INDEX "extindex" +#define KVSPACE_KIND_RWIR "rwir" +#define KVSPACE_KIND_RWFUNC "rwfunc" +#define KVSPACE_KIND_SCOPE "scope" +#define KVSPACE_KIND_TIME "time" +#define KVSPACE_KIND_DURATION "duration" + +/* ── 路径/成员分隔符 ───────────────────────────────────────────────── */ + +#define PATH_SEP "/" +#define DIR_INDEX_SUF "/" +#define MEMBER_SEP "." +#define INDEX_VALUE_SEP "\n" +#define RUNTIME_MEMBER_SEP "\xE2\x80\xA5" /* ‥ U+2025 */ +#define EXT_INDEX_HEAD "\xE2\x80\xA6" /* … U+2026 */ diff --git a/runtime/src/runtime_internal.h b/runtime/src/runtime_internal.h index cae0892c..1aa36e77 100644 --- a/runtime/src/runtime_internal.h +++ b/runtime/src/runtime_internal.h @@ -6,6 +6,7 @@ #include #include #include +#include "const.h" /* ── kvspace-durable C ABI ─────────────────────────────────────────── */ @@ -49,41 +50,7 @@ extern int kvspaceNewBool(uint8_t v, uint8_t **out, uint32_t *out_len); extern int kvspaceNewInt64(int64_t v, uint8_t **out, uint32_t *out_len); extern int kvspaceNewFloat64(double v, uint8_t **out, uint32_t *out_len); -/* ── kind 常量 ─────────────────────────────────────────────────────── */ - -#define KVSPACE_KIND_NONE "None" -#define KVSPACE_KIND_BOOL "bool" -#define KVSPACE_KIND_INT8 "int8" -#define KVSPACE_KIND_INT16 "int16" -#define KVSPACE_KIND_INT32 "int32" -#define KVSPACE_KIND_INT64 "int64" -#define KVSPACE_KIND_UINT8 "uint8" -#define KVSPACE_KIND_UINT16 "uint16" -#define KVSPACE_KIND_UINT32 "uint32" -#define KVSPACE_KIND_UINT64 "uint64" -#define KVSPACE_KIND_FLOAT32 "float32" -#define KVSPACE_KIND_FLOAT64 "float64" -#define KVSPACE_KIND_CHAR "char/utf32" -#define KVSPACE_KIND_CHAR_UTF8 "char/utf8" -#define KVSPACE_KIND_CHAR_ASCII "char/ascii" -#define KVSPACE_KIND_OBJ "obj" -#define KVSPACE_KIND_MAP "map" -#define KVSPACE_KIND_INDEX "index" -#define KVSPACE_KIND_EXT_INDEX "extindex" -#define KVSPACE_KIND_RWIR "rwir" -#define KVSPACE_KIND_RWFUNC "rwfunc" -#define KVSPACE_KIND_SCOPE "scope" -#define KVSPACE_KIND_TIME "time" -#define KVSPACE_KIND_DURATION "duration" - -/* ── 路径/成员常量 ─────────────────────────────────────────────────── */ - -#define PATH_SEP "/" -#define DIR_INDEX_SUF "/" -#define MEMBER_SEP "." -#define INDEX_VALUE_SEP "\n" -#define RUNTIME_MEMBER_SEP "\xE2\x80\xA5" /* ‥ U+2025 */ -#define EXT_INDEX_HEAD "\xE2\x80\xA6" /* … U+2026 */ +/* ── 数值上限 ──────────────────────────────────────────────────────── */ #define MAX_PARAMS 128 #define MAX_STACK_DEPTH 256 diff --git a/runtime/src/type_expr.c b/runtime/src/type_expr.c index 31321c6e..58b99f04 100644 --- a/runtime/src/type_expr.c +++ b/runtime/src/type_expr.c @@ -20,19 +20,20 @@ static bool kind_eq(const char *s, size_t len, const char *k) { /* 精确 kind 集合(对齐 runtime kind 常量,不含 None)。 */ static bool known_kind(const char *s, size_t len) { - return kind_eq(s, len, "bool") || - kind_eq(s, len, "int8") || kind_eq(s, len, "int16") || - kind_eq(s, len, "int32") || kind_eq(s, len, "int64") || - kind_eq(s, len, "uint8") || kind_eq(s, len, "uint16") || - kind_eq(s, len, "uint32") || kind_eq(s, len, "uint64") || - kind_eq(s, len, "float32") || kind_eq(s, len, "float64") || - kind_eq(s, len, "char/utf32") || kind_eq(s, len, "char/utf8") || - kind_eq(s, len, "char/ascii") || - kind_eq(s, len, "obj") || kind_eq(s, len, "index") || - kind_eq(s, len, "extindex") || - kind_eq(s, len, "rwir") || kind_eq(s, len, "rwfunc") || - kind_eq(s, len, "scope") || kind_eq(s, len, "time") || - kind_eq(s, len, "duration"); + return kind_eq(s, len, KVSPACE_KIND_BOOL) || + kind_eq(s, len, KVSPACE_KIND_INT8) || kind_eq(s, len, KVSPACE_KIND_INT16) || + kind_eq(s, len, KVSPACE_KIND_INT32) || kind_eq(s, len, KVSPACE_KIND_INT64) || + kind_eq(s, len, KVSPACE_KIND_UINT8) || kind_eq(s, len, KVSPACE_KIND_UINT16) || + kind_eq(s, len, KVSPACE_KIND_UINT32) || kind_eq(s, len, KVSPACE_KIND_UINT64) || + kind_eq(s, len, KVSPACE_KIND_FLOAT32) || kind_eq(s, len, KVSPACE_KIND_FLOAT64) || + kind_eq(s, len, KVSPACE_KIND_CHAR) || kind_eq(s, len, KVSPACE_KIND_CHAR_UTF8) || + kind_eq(s, len, KVSPACE_KIND_CHAR_ASCII) || + kind_eq(s, len, KVSPACE_KIND_OBJ) || kind_eq(s, len, KVSPACE_KIND_MAP) || + kind_eq(s, len, KVSPACE_KIND_INDEX) || kind_eq(s, len, KVSPACE_KIND_EXT_INDEX) || + kind_eq(s, len, KVSPACE_KIND_RWIR) || kind_eq(s, len, KVSPACE_KIND_RWFUNC) || + kind_eq(s, len, KVSPACE_KIND_SCOPE) || kind_eq(s, len, KVSPACE_KIND_TIME) || + kind_eq(s, len, KVSPACE_KIND_DURATION) || + kind_eq(s, len, "json"); /* json:递归 union,type-only,非落盘 kind */ } /* base = any | kind(kind 为精确合法 kind 串) */ diff --git a/runtime/src/xvalue.c b/runtime/src/xvalue.c index 49cb7f48..44f25d03 100644 --- a/runtime/src/xvalue.c +++ b/runtime/src/xvalue.c @@ -265,15 +265,14 @@ char *kvlangXvalueValueString(const kvlangXvalue_t *v) { return kvlangStrbufDetach(&b); } if (strcmp(k, KVSPACE_KIND_INDEX) == 0) { - int n = 0; - for (int32_t i = 0; i < blen; i++) if (body[i] == '\n') n++; - if (blen > 0) n++; + int n = blen >= 4 ? (int)rd32(body) : 0; kvlangStrbuf_t b; kvlangStrbufInit(&b); kvlangStrbufPrintf(&b, "(%d)", n); return kvlangStrbufDetach(&b); } if (strcmp(k, KVSPACE_KIND_OBJ) == 0) { + int n = blen >= 4 ? (int)rd32(body) : 0; kvlangStrbuf_t b; kvlangStrbufInit(&b); - if (blen == 0) kvlangStrbufPuts(&b, "obj"); - else { int n = 1; for (int32_t i = 0; i < blen; i++) if (body[i] == '\n') n++; kvlangStrbufPrintf(&b, "{%d}", n); } + if (n == 0) kvlangStrbufPuts(&b, KVSPACE_KIND_OBJ); + else kvlangStrbufPrintf(&b, "{%d}", n); return kvlangStrbufDetach(&b); } return strndup2(body, blen); diff --git a/tutorial/04-ndarray/sparse_literal.kv b/tutorial/04-ndarray/sparse_literal.kv index 510d8836..ec4db61f 100644 --- a/tutorial/04-ndarray/sparse_literal.kv +++ b/tutorial/04-ndarray/sparse_literal.kv @@ -1,4 +1,4 @@ -# sparse_literal: 花括号 {..} 字面量 = 散 key 数组(每元素落 base. 独立 key) +# sparse_literal: 花括号 {..} 字面量 = 散 key 数组(每元素落 base.i 独立 key) # 括号规约: [1,2,3] = compact 定长打包进单 XValue;{1,2,3} = 散 key,变长/可增长 # 语义: {..} 只作赋值右值或 for-in 源;for (x in nums) 遍历散 key 元素 # 期望输出: