Refactor Binder to use simpler types
The Binder has been refactored to simplify its internal types and reduce redundancy. Key changes include: - Removed StaticType from LocalInfo, as it's not strictly needed for the binder. - Simplified `define` in CompilerScope to not take a StaticType. - Removed StaticType from upvalues in FunctionCompiler. - Adjusted global mappings to store only the index, not the type. - Updated BoundKind to use a generic type parameter `T` for metadata, defaulting to `()` for untyped bound nodes. - Introduced `BoundNode` and `TypedNode` type aliases for clarity. - Minor adjustments to dumper and VM to accommodate the new generic BoundKind.
This commit is contained in:
@@ -2,15 +2,27 @@ use std::rc::Rc;
|
||||
use crate::ast::types::{Value, StaticType, Identity};
|
||||
use crate::ast::nodes::Node;
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
pub enum Address {
|
||||
Local(u32), // Stack-Slot index (relative to frame base)
|
||||
Upvalue(u32), // Index in the closure's upvalue array
|
||||
Global(u32), // Index in the global environment vector
|
||||
}
|
||||
|
||||
/// 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>>;
|
||||
fn display_name(&self) -> String;
|
||||
}
|
||||
|
||||
impl<T> Clone for Box<dyn BoundExtension<T>> {
|
||||
fn clone(&self) -> Self {
|
||||
self.clone_box()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum BoundKind {
|
||||
pub enum BoundKind<T = ()> {
|
||||
Nop,
|
||||
Constant(Value),
|
||||
|
||||
@@ -20,66 +32,76 @@ pub enum BoundKind {
|
||||
// Variable Update (Assignment)
|
||||
Set {
|
||||
addr: Address,
|
||||
value: Box<Node<BoundKind, StaticType>>,
|
||||
value: Box<Node<BoundKind<T>, T>>,
|
||||
},
|
||||
|
||||
// Variable Declaration (Local)
|
||||
DefLocal {
|
||||
slot: u32,
|
||||
value: Box<Node<BoundKind, StaticType>>,
|
||||
value: Box<Node<BoundKind<T>, T>>,
|
||||
captured_by: Vec<Identity>,
|
||||
},
|
||||
|
||||
If {
|
||||
cond: Box<Node<BoundKind, StaticType>>,
|
||||
then_br: Box<Node<BoundKind, StaticType>>,
|
||||
else_br: Option<Box<Node<BoundKind, StaticType>>>,
|
||||
cond: Box<Node<BoundKind<T>, T>>,
|
||||
then_br: Box<Node<BoundKind<T>, T>>,
|
||||
else_br: Option<Box<Node<BoundKind<T>, T>>>,
|
||||
},
|
||||
|
||||
// Global Definition (Locals are implicit by stack position)
|
||||
DefGlobal {
|
||||
global_index: u32,
|
||||
value: Box<Node<BoundKind, StaticType>>,
|
||||
value: Box<Node<BoundKind<T>, T>>,
|
||||
},
|
||||
|
||||
Lambda {
|
||||
param_count: u32,
|
||||
// The list of variables captured from enclosing scopes
|
||||
upvalues: Vec<Address>,
|
||||
body: Rc<Node<BoundKind, StaticType>>,
|
||||
body: Rc<Node<BoundKind<T>, T>>,
|
||||
},
|
||||
|
||||
Call {
|
||||
callee: Box<Node<BoundKind, StaticType>>,
|
||||
args: Vec<Node<BoundKind, StaticType>>,
|
||||
callee: Box<Node<BoundKind<T>, T>>,
|
||||
args: Vec<Node<BoundKind<T>, T>>,
|
||||
},
|
||||
|
||||
TailCall {
|
||||
callee: Box<Node<BoundKind, StaticType>>,
|
||||
args: Vec<Node<BoundKind, StaticType>>,
|
||||
callee: Box<Node<BoundKind<T>, T>>,
|
||||
args: Vec<Node<BoundKind<T>, T>>,
|
||||
},
|
||||
|
||||
Block {
|
||||
exprs: Vec<Node<BoundKind, StaticType>>,
|
||||
exprs: Vec<Node<BoundKind<T>, T>>,
|
||||
},
|
||||
|
||||
// NEW
|
||||
Tuple {
|
||||
elements: Vec<Node<BoundKind, StaticType>>,
|
||||
elements: Vec<Node<BoundKind<T>, T>>,
|
||||
},
|
||||
|
||||
Map {
|
||||
entries: Vec<(Node<BoundKind, StaticType>, Node<BoundKind, StaticType>)>,
|
||||
entries: Vec<(Node<BoundKind<T>, T>, Node<BoundKind<T>, T>)>,
|
||||
},
|
||||
|
||||
/// An expanded macro call, preserving the original call for debugging and UI.
|
||||
Expansion {
|
||||
/// The original call from the untyped AST.
|
||||
original_call: Rc<Node<crate::ast::nodes::UntypedKind>>,
|
||||
/// The result of binding the expanded AST.
|
||||
bound_expanded: Box<Node<BoundKind, StaticType>>,
|
||||
bound_expanded: Box<Node<BoundKind<T>, T>>,
|
||||
},
|
||||
|
||||
/// DSL-specific extension slot
|
||||
Extension(Box<dyn BoundExtension<T>>),
|
||||
}
|
||||
|
||||
impl BoundKind {
|
||||
/// Type alias for a node that has been bound (addresses resolved) but not yet type-checked.
|
||||
pub type BoundNode = Node<BoundKind<()>, ()>;
|
||||
|
||||
/// Type alias for a node that has been fully type-checked and is ready for execution.
|
||||
pub type TypedNode = Node<BoundKind<StaticType>, StaticType>;
|
||||
|
||||
impl<T> BoundKind<T> {
|
||||
pub fn display_name(&self) -> String {
|
||||
match self {
|
||||
BoundKind::Nop => "NOP".to_string(),
|
||||
@@ -96,6 +118,7 @@ impl BoundKind {
|
||||
BoundKind::Tuple { elements } => format!("TUPLE({})", elements.len()),
|
||||
BoundKind::Map { entries } => format!("MAP({})", entries.len()),
|
||||
BoundKind::Expansion { .. } => "EXPANSION".to_string(),
|
||||
BoundKind::Extension(ext) => ext.display_name(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user