Expand description
§cure-tree
通用 arena 树工具包:为 cure_engine::Lang 的实现语言提供每个语言
都要重复构建的基础设施。一个新语言前端 = 本工具包 + 语言自己的
NodeData / parser / printer / 规则包。
约定(工具包假设的语言形态):
- 节点 = 稠密 arena 下标(
Lang::node_index与Lang::id_of_index互逆;Id: Copy) - 名字键 =
u32intern id(NameTable:名字 ↔ u32只增表 + 每节点名字键表) - children 布局遵循
cure_engine::kind::NodeKind的文档 (Assign =[target, value]等——区域事件收集器按此遍历)
模块:
ChildList:≤3 孩子内联零堆分配的容器(AST 扇出绝大多数 ≤3)NameTable:单元级名字 intern 表 + 节点名字键(增量扩展)EventStore+stmt_roots+collect_region_events: 区域事件索引(B3 惰性重建:只重建被失效的空条目)与泛型事件 收集器(只依赖 Lang 钩子:is_opaque/var_key/kind/children/un_op——与引擎scan_region递归严格同序)rebuild_effects:聚合效果表的不动点重建 (children-先于-parent 索引序 + 注入节点违例的多轮收敛)
集成模式(语言侧 Lang::prepare / invalidate_effect 的标准骨架):
ⓘ
fn prepare(&mut self, root: JavaId) {
// 1) 新节点名字键增量扩展(名字先收集,借用安全)
let names = /* base..count 收集 var_name */;
self.names.extend_owned(base, &names);
// 2) 区域事件索引:B3 只重建空条目
self.events.resize(self.nodes.len());
if !self.events.is_clean() {
self.events.mark_clean();
for sr in cure_tree::stmt_roots(self, root) {
if self.events.slot(sr).is_empty() {
let ev = cure_tree::collect_region_events(self, sr);
self.events.put(self.node_index(sr), ev);
}
}
}
// 3) 效果表
self.effect_cache = cure_tree::rebuild_effects(self, self.nodes.len());
// 4) 语言专属(作用域类型解析等)
}
fn invalidate_effect(&mut self, id: JavaId) {
self.events.invalidate(self.node_index(id));
// + 语言自己的缓存失效
}零外部依赖(仅 cure-engine)。
Structs§
- Child
List - 子节点容器:≤3 个孩子零堆分配(AST 绝大多数节点—— Binary/Assign=2、Member/MethodRef=1、VarDecl≤1、Literal=0…… 大语料 malloc 采样的剩余大头是每节点一次 Vec 堆分配); ≥4 溢出到堆。Block/Call 大参数列表溢出属预期路径。
- Event
Store - 事件存储(稠密:槽位 = arena 下标)+ B3 惰性重建的清洁标记。
- Name
Table - 名字表:单元级「名字 ↔ u32」intern(只增、永不回收)+ 每节点的
名字键(槽位 = arena 下标,
KEY_NONE= 无名)。
Constants§
- KEY_
NONE - 无名节点的键(哨兵:intern id 从 0 只增,实际不可达)。
Functions§
- collect_
region_ events - 收集
node子树的事件序列,按键稳定排序:同键内保持遍历序 (查询侧只消费键内序——Use 的顺序、Write/Shadow 的命中,跨键顺序 无关),二分定位键区间。 - rebuild_
effects - 重建每节点聚合效果表(槽位 = arena 下标)。
- stmt_
roots - 语句级节点枚举:Block 的直接孩子(引擎规则只对这些调用
scan_region)。遍历整树,遇到 Block 就为其每个孩子登记。