Skip to main content

cure_engine/
kind.rs

1//! 规范节点种类表:引擎共享规则所依赖的最小结构词汇表。
2//!
3//! 语言 crate 把自己的 AST 映射到这些 kind 上。这里**不是** Universal AST:
4//! 它只覆盖主流语句/表达式形态,语言特有节点用 [`NodeKind::Custom`] 逃逸,
5//! 由语言 crate 自己的规则处理,引擎通用规则不会触碰。
6//!
7//! 每种 kind 的 children 布局是共享规则的契约(位置即求值/书写顺序):
8
9use std::fmt;
10
11#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, PartialOrd, Ord)]
12pub enum NodeKind {
13    // ---- 语句 ----
14    /// `[stmt…]`
15    Block,
16    /// 空语句 `;`,无 children。
17    Empty,
18    /// `yield expr;`(switch 表达式块内的产出语句)。
19    Yield,
20    /// `[expr]`
21    ExprStmt,
22    /// 局部变量声明,children: `[(init)?]`,名字由 `Lang::var_name` 提供。
23    /// 目标变量必须可写(普通局部变量),声明的类型语义由语言侧保证。
24    VarDecl,
25    /// `[target, value]`;target 必须是 VarRef(复合赋值通过 `Lang::assign_op` 区分)。
26    Assign,
27    /// `[cond, then]` 或 `[cond, then, else]`
28    If,
29    /// `[cond, body]`
30    While,
31    /// `[body, cond]`
32    DoWhile,
33    /// `[(init)?, (cond)?, (step)?, body]`
34    For,
35    /// 增强 for:`[iterable, body]`,变量名/类型为语言侧 attr。
36    ForEach,
37    /// `[(value)?]`
38    Return,
39    /// `[(label)?]`(label 以字符串 attr 提供,不在 children)
40    Break,
41    Continue,
42    /// `[expr]`
43    Throw,
44    /// `[(resource)?, try_block, (catch)?, (finally)?]`;资源是语句节点,catch 子节点。
45    Try,
46    /// `[body]`;参数为语言侧 attr(`var_name` 返回绑定名)。
47    Catch,
48    /// `[lock, block]`
49    Synchronized,
50    /// `[subject, case…]`
51    Switch,
52    /// `[label…, stmts…]`(label 数与是否 default 为语言侧 attr)
53    Case,
54    /// `[stmt]`,标签名为 attr。
55    Label,
56    /// `[(cond, (msg)?)]`
57    Assert,
58
59    // ---- 表达式 ----
60    /// `[lhs, rhs]`,运算符由 `Lang::bin_op` 提供。
61    Binary,
62    /// `[operand]`,运算符由 `Lang::un_op` 提供。
63    Unary,
64    /// `[callee, arg…]`;callee 不能为空。
65    Call,
66    /// 字面量,值由 `Lang::literal` 提供,无 children。
67    Literal,
68    /// 变量读,名字由 `Lang::var_name` 提供。
69    VarRef,
70    /// `[cond, then, else]`
71    Ternary,
72    /// `[expr]`,目标类型为语言侧 attr。
73    Cast,
74    /// `[expr]` 纯括号分组,可被 ParenRemoval 删除。
75    Paren,
76    /// `[object]`,成员名为语言侧 attr(`null` 安全调用等也是语言侧语义)。
77    Member,
78    /// `[array, index]`
79    Index,
80    /// `[arg…]`,构造类型为语言侧 attr。
81    New,
82    /// `[size…, (init)?]`,元素类型与已给尺寸数为语言侧 attr。
83    NewArray,
84    /// `[elem…]`
85    ArrayLit,
86    /// 无 children(或语言侧自定)。
87    This,
88    /// `[expr]`,类型/模式绑定为语言侧 attr。`x instanceof T b`
89    InstanceOf,
90    /// `[body]`(body 为 Block 或表达式),参数原文为语言侧 attr。
91    Lambda,
92    /// `[receiver]`,成员名为语言侧 attr。`recv::name`
93    MethodRef,
94    /// 不可解析的原文区域:语言侧原样保留,通用规则不触碰。
95    Raw,
96    /// 语言特有节点逃逸口;引擎通用规则不匹配。
97    Custom(u16),
98}
99
100impl NodeKind {
101    /// 数组分派用的小整数键:字段变体 Custom 折叠到统一槽位。
102    /// 穷尽 match —— 枚举加变体时编译器强制补分支(不会静默漏桶)。
103    #[inline]
104    pub fn slot(self) -> usize {
105        match self {
106            NodeKind::Block => 0,
107            NodeKind::Empty => 1,
108            NodeKind::Yield => 2,
109            NodeKind::ExprStmt => 2,
110            NodeKind::VarDecl => 3,
111            NodeKind::Assign => 4,
112            NodeKind::If => 5,
113            NodeKind::While => 6,
114            NodeKind::DoWhile => 7,
115            NodeKind::For => 8,
116            NodeKind::ForEach => 9,
117            NodeKind::Return => 10,
118            NodeKind::Break => 11,
119            NodeKind::Continue => 12,
120            NodeKind::Throw => 13,
121            NodeKind::Try => 14,
122            NodeKind::Catch => 15,
123            NodeKind::Synchronized => 16,
124            NodeKind::Switch => 17,
125            NodeKind::Case => 18,
126            NodeKind::Label => 19,
127            NodeKind::Assert => 20,
128            NodeKind::Binary => 21,
129            NodeKind::Unary => 22,
130            NodeKind::Call => 23,
131            NodeKind::Literal => 24,
132            NodeKind::VarRef => 25,
133            NodeKind::Ternary => 26,
134            NodeKind::Cast => 27,
135            NodeKind::Paren => 28,
136            NodeKind::Member => 29,
137            NodeKind::Index => 30,
138            NodeKind::New => 31,
139            NodeKind::NewArray => 32,
140            NodeKind::ArrayLit => 33,
141            NodeKind::This => 34,
142            NodeKind::InstanceOf => 35,
143            NodeKind::Lambda => 36,
144            NodeKind::MethodRef => 37,
145            NodeKind::Raw => 38,
146            NodeKind::Custom(_) => 39,
147        }
148    }
149
150    /// slot 的上界(分派表定容用)。
151    pub const SLOT_COUNT: usize = 42;
152}
153
154impl NodeKind {
155    pub fn is_stmt(self) -> bool {
156        use NodeKind::*;
157        matches!(
158            self,
159            Block | Empty | ExprStmt | VarDecl | Assign | If | While | DoWhile | For | ForEach
160                | Return | Break | Continue | Throw | Switch | Case | Try | Catch
161                | Synchronized | Label | Assert | Raw
162        )
163    }
164}
165
166impl fmt::Display for NodeKind {
167    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
168        write!(f, "{:?}", self)
169    }
170}
171
172/// 二元运算符(规范词汇表,语言负责映射)。
173#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
174pub enum BinOp {
175    Add,
176    Sub,
177    Mul,
178    Div,
179    Rem,
180    Shl,
181    Shr,
182    UShr,
183    Lt,
184    Le,
185    Gt,
186    Ge,
187    Eq,
188    Ne,
189    BitAnd,
190    BitXor,
191    BitOr,
192    And,
193    Or,
194}
195
196impl BinOp {
197    pub fn is_comparison(self) -> bool {
198        matches!(self, BinOp::Lt | BinOp::Le | BinOp::Gt | BinOp::Ge | BinOp::Eq | BinOp::Ne)
199    }
200    pub fn is_short_circuit(self) -> bool {
201        matches!(self, BinOp::And | BinOp::Or)
202    }
203    /// 可能因除零抛异常的运算。
204    pub fn may_div_zero(self) -> bool {
205        matches!(self, BinOp::Div | BinOp::Rem)
206    }
207    /// 整数算术/位运算类(用于精确整数恒等式守卫)。
208    pub fn is_arith(self) -> bool {
209        matches!(
210            self,
211            BinOp::Add
212                | BinOp::Sub
213                | BinOp::Mul
214                | BinOp::Div
215                | BinOp::Rem
216                | BinOp::Shl
217                | BinOp::Shr
218                | BinOp::UShr
219                | BinOp::BitAnd
220                | BinOp::BitXor
221                | BinOp::BitOr
222        )
223    }
224}
225
226/// 一元运算符。
227#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
228pub enum UnOp {
229    Not,
230    Neg,
231    BitNot,
232    /// 一元 `+`(数值提升——char/byte/short 提升 int;装箱类型改变
233    /// `Object o = +c` → Integer 而非 Character)。恒等但**静态类型敏感**,
234    /// 不可丢弃。
235    Plus,
236    /// `++x`(读+写)
237    PreInc,
238    PreDec,
239    /// `x++`(读+写)
240    PostInc,
241    PostDec,
242}
243
244impl UnOp {
245    pub fn is_incdec(self) -> bool {
246        matches!(
247            self,
248            UnOp::PreInc | UnOp::PreDec | UnOp::PostInc | UnOp::PostDec
249        )
250    }
251}
252
253/// 字面量值的借用视图(语言 crate 从自己的负载映射)。
254#[derive(Clone, Copy, PartialEq, Debug)]
255pub enum LitRef<'a> {
256    Bool(bool),
257    Int(i64),
258    Long(i64),
259    Float(f64),
260    Double(f64),
261    Char(char),
262    Str(&'a str),
263    Null,
264}
265
266impl<'a> LitRef<'a> {
267    pub fn is_bool(self) -> bool {
268        matches!(self, LitRef::Bool(_))
269    }
270    /// 整数字面量(Int/Long),返回数值。
271    pub fn as_int(self) -> Option<i64> {
272        match self {
273            LitRef::Int(v) | LitRef::Long(v) => Some(v),
274            _ => None,
275        }
276    }
277}
278
279/// 区域扫描事件(使用索引的原子):语句子树遍历中的一次读/写/遮蔽。
280/// `node` 指向承载名字的节点(Use→VarRef;Write→赋值目标 VarRef 或
281/// 声明节点;Shadow→VarDecl/ForEach/Catch 绑定节点),名字由
282/// `Lang::var_name(node)` 读取——与 scan_region 原递归的判定一致。
283#[derive(Clone, Copy, Debug)]
284pub struct RegionEvent<Id, Key> {
285    pub kind: EventKind,
286    pub node: Id,
287    /// 事件承载者的名字键(语言侧等价类:Java=u32 intern id)——
288    /// 事件构建时预存,查询侧比较为整数等值,免 var_name/memcmp。
289    pub key: Key,
290}
291
292#[derive(Clone, Copy, PartialEq, Eq, Debug)]
293pub enum EventKind {
294    /// 变量读(VarRef)
295    Use,
296    /// 显式局部写(赋值目标 / 自增自减目标 / 声明 / ForEach 绑定)
297    Write,
298    /// 同名遮蔽(VarDecl / ForEach / Catch 声明)
299    Shadow,
300    /// 不透明区域(Raw 不可解析原文):读写集未知——一切"零用途/
301    /// 单用途/无写"的证明失效,规则必须保守拒绝(对抗波 3 抓获:
302    /// 仅被 RAW 引用的变量被误删 + 值被提前传播越过 RAW 赋值)。
303    Opaque,
304}