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    // ---- JS 专用(语言映射词汇;Java 不产生)----
195    /// `**`(幂)。右结合且非结合律——重结合类规则须跳过。
196    Pow,
197    /// `===`(严格相等)。与 [`BinOp::Eq`](宽松 `==`)语义不同:
198    /// 折叠规则必须按语言语义分别处理。
199    StrictEq,
200    /// `!==`(严格不等)。
201    StrictNe,
202    /// `??`(空值合并——**非短路布尔**:返回操作数值而非布尔)。
203    Nullish,
204    /// `in`(属性存在性,二元关系)。
205    In,
206    /// `instanceof`(JS 的二元运算形态,RHS 是任意表达式)。
207    Instanceof,
208}
209
210impl BinOp {
211    pub fn is_comparison(self) -> bool {
212        matches!(
213            self,
214            BinOp::Lt
215                | BinOp::Le
216                | BinOp::Gt
217                | BinOp::Ge
218                | BinOp::Eq
219                | BinOp::Ne
220                | BinOp::StrictEq
221                | BinOp::StrictNe
222                | BinOp::In
223                | BinOp::Instanceof
224        )
225    }
226    pub fn is_short_circuit(self) -> bool {
227        matches!(self, BinOp::And | BinOp::Or | BinOp::Nullish)
228    }
229    /// 可能因除零抛异常的运算。
230    pub fn may_div_zero(self) -> bool {
231        matches!(self, BinOp::Div | BinOp::Rem)
232    }
233    /// 整数算术/位运算类(用于精确整数恒等式守卫)。
234    pub fn is_arith(self) -> bool {
235        matches!(
236            self,
237            BinOp::Add
238                | BinOp::Sub
239                | BinOp::Mul
240                | BinOp::Div
241                | BinOp::Rem
242                | BinOp::Shl
243                | BinOp::Shr
244                | BinOp::UShr
245                | BinOp::BitAnd
246                | BinOp::BitXor
247                | BinOp::BitOr
248        )
249    }
250}
251
252/// 一元运算符。
253#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
254pub enum UnOp {
255    Not,
256    Neg,
257    BitNot,
258    // ---- JS 专用(语言映射词汇;Java 不产生)----
259    /// `typeof x`(值恒为字符串;对未声明变量**不抛**——效果 Pure)。
260    TypeOf,
261    /// `void x`(求值操作数、返回 undefined——效果含操作数)。
262    Void,
263    /// `delete x`(可能写:删属性)。
264    Delete,
265    /// `await x`(仅在 async 函数内;暂停语义——效果 Unknown)。
266    Await,
267    /// 一元 `+`(数值提升——char/byte/short 提升 int;装箱类型改变
268    /// `Object o = +c` → Integer 而非 Character)。恒等但**静态类型敏感**,
269    /// 不可丢弃。
270    Plus,
271    /// `++x`(读+写)
272    PreInc,
273    PreDec,
274    /// `x++`(读+写)
275    PostInc,
276    PostDec,
277}
278
279impl UnOp {
280    pub fn is_incdec(self) -> bool {
281        matches!(
282            self,
283            UnOp::PreInc | UnOp::PreDec | UnOp::PostInc | UnOp::PostDec
284        )
285    }
286}
287
288/// 字面量值的借用视图(语言 crate 从自己的负载映射)。
289#[derive(Clone, Copy, PartialEq, Debug)]
290pub enum LitRef<'a> {
291    Bool(bool),
292    Int(i64),
293    Long(i64),
294    Float(f64),
295    Double(f64),
296    Char(char),
297    Str(&'a str),
298    Null,
299}
300
301impl<'a> LitRef<'a> {
302    pub fn is_bool(self) -> bool {
303        matches!(self, LitRef::Bool(_))
304    }
305    /// 整数字面量(Int/Long),返回数值。
306    pub fn as_int(self) -> Option<i64> {
307        match self {
308            LitRef::Int(v) | LitRef::Long(v) => Some(v),
309            _ => None,
310        }
311    }
312}
313
314/// 区域扫描事件(使用索引的原子):语句子树遍历中的一次读/写/遮蔽。
315/// `node` 指向承载名字的节点(Use→VarRef;Write→赋值目标 VarRef 或
316/// 声明节点;Shadow→VarDecl/ForEach/Catch 绑定节点),名字由
317/// `Lang::var_name(node)` 读取——与 scan_region 原递归的判定一致。
318#[derive(Clone, Copy, Debug)]
319pub struct RegionEvent<Id, Key> {
320    pub kind: EventKind,
321    pub node: Id,
322    /// 事件承载者的名字键(语言侧等价类:Java=u32 intern id)——
323    /// 事件构建时预存,查询侧比较为整数等值,免 var_name/memcmp。
324    pub key: Key,
325}
326
327#[derive(Clone, Copy, PartialEq, Eq, Debug)]
328pub enum EventKind {
329    /// 变量读(VarRef)
330    Use,
331    /// 显式局部写(赋值目标 / 自增自减目标 / 声明 / ForEach 绑定)
332    Write,
333    /// 同名遮蔽(VarDecl / ForEach / Catch 声明)
334    Shadow,
335    /// 不透明区域(Raw 不可解析原文):读写集未知——一切"零用途/
336    /// 单用途/无写"的证明失效,规则必须保守拒绝(对抗波 3 抓获:
337    /// 仅被 RAW 引用的变量被误删 + 值被提前传播越过 RAW 赋值)。
338    Opaque,
339}