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:
+15
-10
@@ -2,13 +2,13 @@ use std::rc::Rc;
|
||||
use std::cell::RefCell;
|
||||
use std::collections::HashMap;
|
||||
use std::any::Any;
|
||||
use crate::ast::compiler::bound_nodes::{Address, BoundKind};
|
||||
use crate::ast::compiler::bound_nodes::{Address, BoundKind, TypedNode};
|
||||
use crate::ast::nodes::Node;
|
||||
use crate::ast::types::{Value, Object, StaticType};
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Closure {
|
||||
pub function_node: Rc<Node<BoundKind, StaticType>>,
|
||||
pub function_node: Rc<TypedNode>,
|
||||
pub upvalues: Vec<Rc<RefCell<Value>>>,
|
||||
}
|
||||
|
||||
@@ -30,8 +30,8 @@ struct CallFrame {
|
||||
/// Hook for observing VM execution (zero-cost when O::ACTIVE is false)
|
||||
pub trait VMObserver {
|
||||
const ACTIVE: bool = false;
|
||||
fn before_eval(&mut self, _vm: &VM, _node: &Node<BoundKind, StaticType>) {}
|
||||
fn after_eval(&mut self, _vm: &VM, _node: &Node<BoundKind, StaticType>, _res: &Result<Value, String>) {}
|
||||
fn before_eval(&mut self, _vm: &VM, _node: &TypedNode) {}
|
||||
fn after_eval(&mut self, _vm: &VM, _node: &TypedNode, _res: &Result<Value, String>) {}
|
||||
}
|
||||
|
||||
/// Default observer that does nothing and should be optimized away
|
||||
@@ -63,13 +63,13 @@ impl Default for TracingObserver {
|
||||
impl VMObserver for TracingObserver {
|
||||
const ACTIVE: bool = true;
|
||||
|
||||
fn before_eval(&mut self, _vm: &VM, node: &Node<BoundKind, StaticType>) {
|
||||
fn before_eval(&mut self, _vm: &VM, node: &TypedNode) {
|
||||
let pad = self.pad();
|
||||
self.logs.push(format!("{}{} [{}]: {{", pad, node.kind.display_name(), node.ty));
|
||||
self.indent += 1;
|
||||
}
|
||||
|
||||
fn after_eval(&mut self, vm: &VM, node: &Node<BoundKind, StaticType>, res: &Result<Value, String>) {
|
||||
fn after_eval(&mut self, vm: &VM, node: &TypedNode, res: &Result<Value, String>) {
|
||||
self.indent = self.indent.saturating_sub(1);
|
||||
let pad = self.pad();
|
||||
|
||||
@@ -262,6 +262,11 @@ macro_rules! dispatch_eval {
|
||||
BoundKind::Expansion { original_call: _, bound_expanded } => {
|
||||
$self.$eval_method($($observer,)? bound_expanded)
|
||||
}
|
||||
|
||||
BoundKind::Extension(ext) => {
|
||||
// Future: Delegate execution to extension
|
||||
Err(format!("Execution of extension '{}' not implemented yet", ext.display_name()))
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -275,7 +280,7 @@ impl VM {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn run(&mut self, root: &Node<BoundKind, StaticType>) -> Result<Value, String> {
|
||||
pub fn run(&mut self, root: &TypedNode) -> Result<Value, String> {
|
||||
self.stack.clear();
|
||||
self.frames.clear();
|
||||
|
||||
@@ -290,7 +295,7 @@ impl VM {
|
||||
result
|
||||
}
|
||||
|
||||
pub fn run_with_observer<O: VMObserver>(&mut self, observer: &mut O, root: &Node<BoundKind, StaticType>) -> Result<Value, String> {
|
||||
pub fn run_with_observer<O: VMObserver>(&mut self, observer: &mut O, root: &TypedNode) -> Result<Value, String> {
|
||||
self.stack.clear();
|
||||
self.frames.clear();
|
||||
|
||||
@@ -307,12 +312,12 @@ impl VM {
|
||||
|
||||
/// The pure, original, zero-cost hot path.
|
||||
#[inline(always)]
|
||||
fn eval(&mut self, node: &Node<BoundKind, StaticType>) -> Result<Value, String> {
|
||||
fn eval(&mut self, node: &TypedNode) -> Result<Value, String> {
|
||||
dispatch_eval!(self, node, eval)
|
||||
}
|
||||
|
||||
/// The observed path for debugging.
|
||||
fn eval_observed<O: VMObserver>(&mut self, observer: &mut O, node: &Node<BoundKind, StaticType>) -> Result<Value, String> {
|
||||
fn eval_observed<O: VMObserver>(&mut self, observer: &mut O, node: &TypedNode) -> Result<Value, String> {
|
||||
observer.before_eval(self, node);
|
||||
|
||||
// Wrap in a closure to ensure after_eval is called even on early returns (e.g. from ?)
|
||||
|
||||
Reference in New Issue
Block a user