Skip to main content

cure_tree/
events.rs

1//! 区域事件索引:存储 + 泛型收集器。
2
3use cure_engine::kind::{EventKind, NodeKind, RegionEvent};
4use cure_engine::Lang;
5
6/// 事件存储(稠密:槽位 = arena 下标)+ B3 惰性重建的清洁标记。
7///
8/// 「空序列 = 未索引」是三重哨兵:未构建、被 `invalidate` 失效、或
9/// 子树含不透明节点(不建索引——键排序分区看不见 Opaque 键,查询侧
10/// 走引擎的 `scan_region` 递归路径,其 Opaque 分支保守拒绝)。
11#[derive(Debug)]
12pub struct EventStore<Id, NameKey> {
13    events: Vec<Vec<RegionEvent<Id, NameKey>>>,
14    clean: bool,
15}
16
17impl<Id, NameKey> Default for EventStore<Id, NameKey> {
18    fn default() -> Self {
19        Self { events: Vec::new(), clean: false }
20    }
21}
22
23impl<Id: Clone, NameKey: Clone> EventStore<Id, NameKey> {
24    pub fn new() -> Self {
25        Self::default()
26    }
27
28    /// 槽位扩到 `count`(不缩;新槽为空 = 未索引)。
29    pub fn resize(&mut self, count: usize) {
30        if self.events.len() < count {
31            self.events.resize(count, Vec::new());
32        }
33    }
34
35    /// 空槽 = 未索引(调用方回落引擎递归路径)。
36    pub fn slot(&self, idx: usize) -> &[RegionEvent<Id, NameKey>] {
37        self.events.get(idx).map(|v| v.as_slice()).unwrap_or(&[])
38    }
39
40    pub fn put(&mut self, idx: usize, events: Vec<RegionEvent<Id, NameKey>>) {
41        if self.events.len() <= idx {
42            self.events.resize(idx + 1, Vec::new());
43        }
44        self.events[idx] = events;
45    }
46
47    pub fn is_clean(&self) -> bool {
48        self.clean
49    }
50    pub fn mark_clean(&mut self) {
51        self.clean = true;
52    }
53
54    /// 失效一个语句条目(编辑沿祖先链调用):清空该槽 + 整表脏标记
55    /// (B3:下次 prepare 只重建**空**条目——未失效条目的事件是子树
56    /// 局部的,与位置无关)。
57    pub fn invalidate(&mut self, idx: usize) {
58        self.clean = false;
59        if let Some(slot) = self.events.get_mut(idx) {
60            slot.clear();
61        }
62    }
63}
64
65/// 语句级节点枚举:Block 的直接孩子(引擎规则只对这些调用
66/// `scan_region`)。遍历整树,遇到 Block 就为其每个孩子登记。
67pub fn stmt_roots<L: Lang>(lang: &L, root: L::Id) -> Vec<L::Id> {
68    let mut stack = vec![root];
69    let mut stmt_roots: Vec<L::Id> = Vec::new();
70    while let Some(n) = stack.pop() {
71        if lang.kind(n) == NodeKind::Block {
72            for &c in lang.children(n) {
73                stmt_roots.push(c);
74            }
75        }
76        for &c in lang.children(n) {
77            stack.push(c);
78        }
79    }
80    stmt_roots
81}
82
83/// 收集 `node` 子树的事件序列,**按键稳定排序**:同键内保持遍历序
84/// (查询侧只消费键内序——Use 的顺序、Write/Shadow 的命中,跨键顺序
85/// 无关),二分定位键区间。
86///
87/// 返回空 Vec = 子树含不透明节点(调用方存空 = 未索引哨兵)。
88/// 事件序与引擎 `scan_region` 原递归**严格一致**(分配器 dispatch 的
89/// 是同一组 Lang 钩子)。
90pub fn collect_region_events<L: Lang>(
91    lang: &L,
92    node: L::Id,
93) -> Vec<RegionEvent<L::Id, L::NameKey>> {
94    let mut out = Vec::new();
95    let opaque = collect_events_into(lang, node, &mut out);
96    if opaque {
97        return Vec::new();
98    }
99    out.sort_by_key(|e| e.key);
100    out
101}
102
103/// 返回值:子树是否含不透明节点(读/写集不可证明)。
104fn collect_events_into<L: Lang>(
105    lang: &L,
106    node: L::Id,
107    out: &mut Vec<RegionEvent<L::Id, L::NameKey>>,
108) -> bool {
109    if lang.is_opaque(node) {
110        return true;
111    }
112    match lang.kind(node) {
113        // 赋值:目标是简单变量 → 对其名字写入;事件节点记 target。
114        // 只递归 RHS(target 的读不算事件——写即事件)。
115        NodeKind::Assign => {
116            let ch = lang.children(node);
117            if let Some(&t) = ch.first() {
118                if lang.kind(t) == NodeKind::VarRef {
119                    if let Some(k) = lang.var_key(t) {
120                        out.push(RegionEvent { kind: EventKind::Write, node: t, key: k });
121                    }
122                }
123            }
124            match ch.get(1) {
125                Some(&v) => collect_events_into(lang, v, out),
126                None => false,
127            }
128        }
129        // 自增/自减:对目标写入(目标自身不再产生读事件)
130        NodeKind::Unary if lang.un_op(node).is_some_and(|o| o.is_incdec()) => {
131            if let Some(&t) = lang.children(node).first() {
132                if lang.kind(t) == NodeKind::VarRef {
133                    if let Some(k) = lang.var_key(t) {
134                        out.push(RegionEvent { kind: EventKind::Write, node: t, key: k });
135                    }
136                }
137            }
138            false
139        }
140        // 声明:写 + 遮蔽(事件节点 = 声明节点自身),全孩子递归
141        NodeKind::VarDecl | NodeKind::ForEach => {
142            if let Some(k) = lang.var_key(node) {
143                out.push(RegionEvent { kind: EventKind::Write, node, key: k });
144                out.push(RegionEvent { kind: EventKind::Shadow, node, key: k });
145            }
146            let mut opaque = false;
147            for &c in lang.children(node) {
148                opaque |= collect_events_into(lang, c, out);
149            }
150            opaque
151        }
152        // catch 绑定:仅遮蔽
153        NodeKind::Catch => {
154            if let Some(k) = lang.var_key(node) {
155                out.push(RegionEvent { kind: EventKind::Shadow, node, key: k });
156            }
157            let mut opaque = false;
158            for &c in lang.children(node) {
159                opaque |= collect_events_into(lang, c, out);
160            }
161            opaque
162        }
163        NodeKind::VarRef => {
164            if let Some(k) = lang.var_key(node) {
165                out.push(RegionEvent { kind: EventKind::Use, node, key: k });
166            }
167            false
168        }
169        _ => {
170            let mut opaque = false;
171            for &c in lang.children(node) {
172                opaque |= collect_events_into(lang, c, out);
173            }
174            opaque
175        }
176    }
177}