Refactor optimizer utilities

Removes unused `flatten_tuple` function from optimizer utilities. The
functionality was moved to the `Folder` struct, making it more
contextually appropriate. This change streamlines the utility module and
improves code organization.
This commit is contained in:
Michael Schimmel
2026-02-25 21:26:12 +01:00
parent cf87bbeac5
commit 81c805f07e
6 changed files with 456 additions and 460 deletions
+82 -83
View File
@@ -1,83 +1,82 @@
use crate::ast::compiler::bound_nodes::{Address, AnalyzedNode, BoundKind, NodeMetrics};
use crate::ast::nodes::Node;
use crate::ast::types::{Purity, StaticType, Value};
use std::cell::RefCell;
use std::rc::Rc;
use super::utils::flatten_tuple;
pub struct Folder<'a> {
pub globals: &'a Option<Rc<RefCell<Vec<Value>>>>,
}
impl<'a> Folder<'a> {
pub fn new(globals: &'a Option<Rc<RefCell<Vec<Value>>>>) -> Self {
Self { globals }
}
pub fn make_constant_node(&self, val: Value, template: &AnalyzedNode) -> AnalyzedNode {
let ty = val.static_type();
let typed_original = Rc::new(Node {
identity: template.identity.clone(),
kind: BoundKind::Constant(val.clone()),
ty: ty.clone(),
});
Node {
identity: template.identity.clone(),
kind: BoundKind::Constant(val),
ty: NodeMetrics {
original: typed_original,
purity: Purity::Pure,
is_recursive: false,
},
}
}
pub fn make_nop_node(&self, template: &AnalyzedNode) -> AnalyzedNode {
let typed_original = Rc::new(Node {
identity: template.identity.clone(),
kind: BoundKind::Nop,
ty: StaticType::Void,
});
Node {
identity: template.identity.clone(),
kind: BoundKind::Nop,
ty: NodeMetrics {
original: typed_original,
purity: Purity::Pure,
is_recursive: false,
},
}
}
pub fn try_fold_pure(&self, callee: &AnalyzedNode, args: &AnalyzedNode) -> Option<AnalyzedNode> {
if callee.ty.purity < Purity::Pure || args.ty.purity < Purity::Pure {
return None;
}
let mut arg_nodes = Vec::new();
flatten_tuple(args.clone(), &mut arg_nodes);
let mut arg_values = Vec::with_capacity(arg_nodes.len());
for node in arg_nodes {
if let BoundKind::Constant(val) = node.kind {
arg_values.push(val);
} else {
return None;
}
}
let func_val = match &callee.kind {
BoundKind::Get {
addr: Address::Global(idx),
..
} => self.globals.as_ref()?.borrow().get(idx.0 as usize)?.clone(),
BoundKind::Constant(val) => val.clone(),
_ => return None,
};
let result = match func_val {
Value::Function(f) => (f.func)(arg_values),
_ => return None,
};
Some(self.make_constant_node(result, callee))
}
}
use crate::ast::compiler::bound_nodes::{Address, AnalyzedNode, BoundKind, NodeMetrics};
use crate::ast::nodes::Node;
use crate::ast::types::{Purity, StaticType, Value};
use std::cell::RefCell;
use std::rc::Rc;
pub struct Folder<'a> {
pub globals: &'a Option<Rc<RefCell<Vec<Value>>>>,
}
impl<'a> Folder<'a> {
pub fn new(globals: &'a Option<Rc<RefCell<Vec<Value>>>>) -> Self {
Self { globals }
}
pub fn make_constant_node(&self, val: Value, template: &AnalyzedNode) -> AnalyzedNode {
let ty = val.static_type();
let typed_original = Rc::new(Node {
identity: template.identity.clone(),
kind: BoundKind::Constant(val.clone()),
ty: ty.clone(),
});
Node {
identity: template.identity.clone(),
kind: BoundKind::Constant(val),
ty: NodeMetrics {
original: typed_original,
purity: Purity::Pure,
is_recursive: false,
},
}
}
pub fn make_nop_node(&self, template: &AnalyzedNode) -> AnalyzedNode {
let typed_original = Rc::new(Node {
identity: template.identity.clone(),
kind: BoundKind::Nop,
ty: StaticType::Void,
});
Node {
identity: template.identity.clone(),
kind: BoundKind::Nop,
ty: NodeMetrics {
original: typed_original,
purity: Purity::Pure,
is_recursive: false,
},
}
}
pub fn try_fold_pure(
&self,
callee: &AnalyzedNode,
arg_nodes: &[AnalyzedNode],
) -> Option<AnalyzedNode> {
if callee.ty.purity < Purity::Pure {
return None;
}
let mut arg_values = Vec::with_capacity(arg_nodes.len());
for node in arg_nodes {
if let BoundKind::Constant(val) = &node.kind {
arg_values.push(val.clone());
} else {
return None;
}
}
let func_val = match &callee.kind {
BoundKind::Get {
addr: Address::Global(idx),
..
} => self.globals.as_ref()?.borrow().get(idx.0 as usize)?.clone(),
BoundKind::Constant(val) => val.clone(),
_ => return None,
};
let result = match func_val {
Value::Function(f) => (f.func)(arg_values),
_ => return None,
};
Some(self.make_constant_node(result, callee))
}
}