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:
@@ -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,
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user