Refactor: Analyze node purity and recursion

The Analyzer has been refactored to decorate `TypedNode`s with their
purity and recursion status. This involves creating a new `AnalyzedNode`
type and a `NodeMetrics` struct to hold this information. The `Analyzer`
now returns an `AnalyzedNode` instead of a separate `Analysis` struct.
This change lays the groundwork for future optimizations and analysis
passes.
This commit is contained in:
Michael Schimmel
2026-02-22 16:11:46 +01:00
parent 8f7947bde1
commit 2fdeff1db4
7 changed files with 503 additions and 1130 deletions
+8 -9
View File
@@ -1,16 +1,15 @@
use crate::ast::compiler::bound_nodes::{BoundKind, TypedNode};
use crate::ast::compiler::bound_nodes::{AnalyzedNode, BoundKind};
use crate::ast::nodes::Node;
use crate::ast::types::StaticType;
use std::rc::Rc;
use std::fmt::Debug;
#[derive(Clone)]
pub struct RuntimeMetadata {
pub ty: StaticType,
pub is_tail: bool,
/// The original, high-level typed node. Perfect for Debuggers and Optimizers.
pub original: Rc<TypedNode>,
/// The analyzed node, containing metrics and a link to the original TypedNode.
pub original: Rc<AnalyzedNode>,
}
impl Debug for RuntimeMetadata {
@@ -22,18 +21,18 @@ impl Debug for RuntimeMetadata {
}
}
/// The ExecNode is the AST used by the VM. It carries TCO flags and links to source.
/// The ExecNode is the AST used by the VM. It carries TCO flags and links to metrics.
pub type ExecNode = Node<BoundKind<RuntimeMetadata>, RuntimeMetadata>;
pub struct TCO;
impl TCO {
/// Lowers a TypedNode (Compiler-AST) to an ExecNode (VM-AST) and marks tail positions.
pub fn optimize(node: TypedNode) -> ExecNode {
/// Lowers an AnalyzedNode to an ExecNode and marks tail positions.
pub fn optimize(node: AnalyzedNode) -> ExecNode {
Self::transform(Rc::new(node), true)
}
fn transform(node_rc: Rc<TypedNode>, is_tail_position: bool) -> ExecNode {
fn transform(node_rc: Rc<AnalyzedNode>, is_tail_position: bool) -> ExecNode {
let node = &*node_rc;
let new_kind = match &node.kind {
BoundKind::Call { callee, args } => BoundKind::Call {
@@ -158,7 +157,7 @@ impl TCO {
identity: node.identity.clone(),
kind: new_kind,
ty: RuntimeMetadata {
ty: node.ty.clone(),
ty: node.ty.original.ty.clone(),
is_tail: is_tail_position,
original: node_rc,
},