Refactor: Use generic Define bound kind

This commit consolidates `DefLocal` and `DefGlobal` into a single
`Define` bound kind. This simplifies the AST and makes it more
consistent.

It also introduces `DeclarationKind` to differentiate between variable
and parameter definitions.
This commit is contained in:
Michael Schimmel
2026-02-25 10:45:36 +01:00
parent f995aaf81b
commit c256a8a992
11 changed files with 280 additions and 464 deletions
+23 -43
View File
@@ -9,6 +9,12 @@ pub enum Address {
Global(u32), // Index in the global environment vector
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum DeclarationKind {
Variable,
Parameter,
}
/// Trait for DSL-specific AST extensions (like Pipe, Series-Access, etc.)
pub trait BoundExtension<T>: std::fmt::Debug {
fn clone_box(&self) -> Box<dyn BoundExtension<T>>;
@@ -43,12 +49,6 @@ pub enum BoundKind<T = ()> {
Nop,
Constant(Value),
/// A positional parameter in a Lambda's parameter list.
Parameter {
name: Symbol,
slot: u32,
},
// Variable Access (Resolved)
Get {
addr: Address,
@@ -61,10 +61,11 @@ pub enum BoundKind<T = ()> {
value: Box<BoundNode<T>>,
},
// Variable Declaration (Local)
DefLocal {
// Variable Declaration (Unified for Local/Global/Parameter)
Define {
name: Symbol,
slot: u32,
addr: Address,
kind: DeclarationKind,
value: Box<BoundNode<T>>,
captured_by: Vec<Identity>,
},
@@ -75,13 +76,6 @@ pub enum BoundKind<T = ()> {
else_br: Option<Box<BoundNode<T>>>,
},
// Global Definition (Locals are implicit by stack position)
DefGlobal {
name: Symbol,
global_index: u32,
value: Box<BoundNode<T>>,
},
/// A destructuring operation (can be a definition or an assignment depending on the pattern)
Destructure {
pattern: Box<BoundNode<T>>,
@@ -138,10 +132,6 @@ where
match (self, other) {
(BoundKind::Nop, BoundKind::Nop) => true,
(BoundKind::Constant(a), BoundKind::Constant(b)) => a == b,
(
BoundKind::Parameter { name: na, slot: sa },
BoundKind::Parameter { name: nb, slot: sb },
) => na == nb && sa == sb,
(BoundKind::Get { addr: aa, name: na }, BoundKind::Get { addr: ab, name: nb }) => {
aa == ab && na == nb
}
@@ -156,19 +146,21 @@ where
},
) => aa == ab && va == vb,
(
BoundKind::DefLocal {
BoundKind::Define {
name: na,
slot: sa,
addr: aa,
kind: ka,
value: va,
captured_by: ca,
},
BoundKind::DefLocal {
BoundKind::Define {
name: nb,
slot: sb,
addr: ab,
kind: kb,
value: vb,
captured_by: cb,
},
) => na == nb && sa == sb && va == vb && ca == cb,
) => na == nb && aa == ab && ka == kb && va == vb && ca == cb,
(
BoundKind::If {
cond: ca,
@@ -181,18 +173,6 @@ where
else_br: eb,
},
) => ca == cb && ta == tb && ea == eb,
(
BoundKind::DefGlobal {
name: na,
global_index: ga,
value: va,
},
BoundKind::DefGlobal {
name: nb,
global_index: gb,
value: vb,
},
) => na == nb && ga == gb && va == vb,
(
BoundKind::Destructure {
pattern: pa,
@@ -255,16 +235,16 @@ impl<T> BoundKind<T> {
match self {
BoundKind::Nop => "NOP".to_string(),
BoundKind::Constant(v) => format!("CONST({})", v),
BoundKind::Parameter { name, slot } => format!("PARAM({}, Slot:{})", name.name, slot),
BoundKind::Get { addr, name } => format!("GET({}, {:?})", name.name, addr),
BoundKind::Set { addr, .. } => format!("SET({:?})", addr),
BoundKind::DefLocal { name, slot, .. } => {
format!("DEF_LOCAL({}, Slot:{})", name.name, slot)
BoundKind::Define { name, addr, kind, .. } => {
let k_str = match kind {
DeclarationKind::Variable => "VAR",
DeclarationKind::Parameter => "PARAM",
};
format!("DEF_{}({}, {:?})", k_str, name.name, addr)
}
BoundKind::If { .. } => "IF".to_string(),
BoundKind::DefGlobal {
name, global_index, ..
} => format!("DEF_GLOBAL({}, Idx:{})", name.name, global_index),
BoundKind::Destructure { .. } => "DESTRUCTURE".to_string(),
BoundKind::Lambda {
params, upvalues, ..