Add type aliases for registries

Introduces `GlobalFunctionRegistry` and `GlobalAnalyzedRegistry` type
aliases to clarify the usage of `HashMap`s for storing global functions
and their analyzed versions. This change also refactors the
`LambdaCollector` and `Optimizer` to use these new aliases, improving
code readability and maintainability.
This commit is contained in:
Michael Schimmel
2026-03-03 15:51:47 +01:00
parent a18642fd7b
commit 078b520c37
6 changed files with 94 additions and 82 deletions
+6
View File
@@ -60,6 +60,9 @@ pub type BoundNode<T = ()> = Node<BoundKind<T>, T>;
/// Type alias for a node that has been fully type-checked. /// Type alias for a node that has been fully type-checked.
pub type TypedNode = BoundNode<StaticType>; pub type TypedNode = BoundNode<StaticType>;
/// Type alias for the global function registry.
pub type GlobalFunctionRegistry = std::collections::HashMap<GlobalIdx, Rc<BoundNode>>;
/// Metrics collected during the analysis phase. /// Metrics collected during the analysis phase.
#[derive(Debug, Clone, PartialEq)] #[derive(Debug, Clone, PartialEq)]
pub struct NodeMetrics { pub struct NodeMetrics {
@@ -71,6 +74,9 @@ pub struct NodeMetrics {
/// Type alias for a node that has been analyzed. /// Type alias for a node that has been analyzed.
pub type AnalyzedNode = BoundNode<NodeMetrics>; pub type AnalyzedNode = BoundNode<NodeMetrics>;
/// Type alias for the global analyzed function registry.
pub type GlobalAnalyzedRegistry = std::collections::HashMap<GlobalIdx, Rc<AnalyzedNode>>;
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub enum BoundKind<T = ()> { pub enum BoundKind<T = ()> {
Nop, Nop,
+5 -4
View File
@@ -1,15 +1,16 @@
use crate::ast::compiler::bound_nodes::{Address, BoundKind, BoundNode, GlobalIdx}; use crate::ast::compiler::bound_nodes::{Address, BoundKind, BoundNode, GlobalIdx};
use std::collections::HashMap; use std::collections::HashMap;
use std::rc::Rc;
/// A pass that collects all global function definitions (lambdas) into a registry. /// A pass that collects all global function definitions (lambdas) into a registry.
/// This allows the Specializer to retrieve the original AST of a function for monomorphization. /// This allows the Specializer to retrieve the original AST of a function for monomorphization.
pub struct LambdaCollector<'a, T> { pub struct LambdaCollector<'a, T> {
registry: &'a mut HashMap<GlobalIdx, BoundNode<T>>, registry: &'a mut HashMap<GlobalIdx, Rc<BoundNode<T>>>,
} }
impl<'a, T: Clone> LambdaCollector<'a, T> { impl<'a, T: Clone> LambdaCollector<'a, T> {
/// Performs a full traversal of the AST and populates the provided registry. /// Performs a full traversal of the AST and populates the provided registry.
pub fn collect(node: &BoundNode<T>, registry: &'a mut HashMap<GlobalIdx, BoundNode<T>>) { pub fn collect(node: &BoundNode<T>, registry: &'a mut HashMap<GlobalIdx, Rc<BoundNode<T>>>) {
let mut collector = Self { registry }; let mut collector = Self { registry };
collector.visit(node); collector.visit(node);
} }
@@ -32,7 +33,7 @@ impl<'a, T: Clone> LambdaCollector<'a, T> {
if let BoundKind::Lambda { .. } = &current.kind { if let BoundKind::Lambda { .. } = &current.kind {
self.registry self.registry
.insert(*global_index, (*current).as_ref().clone()); .insert(*global_index, Rc::new((**current).clone()));
} }
} }
self.visit(value); self.visit(value);
@@ -48,7 +49,7 @@ impl<'a, T: Clone> LambdaCollector<'a, T> {
if let BoundKind::Lambda { .. } = &current.kind { if let BoundKind::Lambda { .. } = &current.kind {
self.registry self.registry
.insert(*global_index, (*current).as_ref().clone()); .insert(*global_index, Rc::new((**current).clone()));
} }
} }
self.visit(value); self.visit(value);
+5 -3
View File
@@ -1,4 +1,6 @@
use crate::ast::compiler::bound_nodes::{Address, AnalyzedNode, BoundKind, GlobalIdx, UpvalueIdx}; use crate::ast::compiler::bound_nodes::{
Address, AnalyzedNode, BoundKind, GlobalAnalyzedRegistry, GlobalIdx, UpvalueIdx,
};
use crate::ast::nodes::Node; use crate::ast::nodes::Node;
use crate::ast::types::{Purity, Value}; use crate::ast::types::{Purity, Value};
use crate::ast::vm::Closure; use crate::ast::vm::Closure;
@@ -16,7 +18,7 @@ pub struct Optimizer {
max_passes: usize, max_passes: usize,
pub globals: Option<Rc<RefCell<Vec<Value>>>>, pub globals: Option<Rc<RefCell<Vec<Value>>>>,
pub global_purity: Option<Rc<RefCell<HashMap<GlobalIdx, Purity>>>>, pub global_purity: Option<Rc<RefCell<HashMap<GlobalIdx, Purity>>>>,
pub lambda_registry: Option<Rc<RefCell<HashMap<GlobalIdx, AnalyzedNode>>>>, pub lambda_registry: Option<Rc<RefCell<GlobalAnalyzedRegistry>>>,
} }
impl Optimizer { impl Optimizer {
@@ -42,7 +44,7 @@ impl Optimizer {
pub fn with_registry( pub fn with_registry(
mut self, mut self,
registry: Rc<RefCell<HashMap<GlobalIdx, AnalyzedNode>>>, registry: Rc<RefCell<GlobalAnalyzedRegistry>>,
) -> Self { ) -> Self {
self.lambda_registry = Some(registry); self.lambda_registry = Some(registry);
self self
+3 -3
View File
@@ -11,12 +11,12 @@ pub struct MonoCacheKey {
pub arg_types: Vec<StaticType>, pub arg_types: Vec<StaticType>,
} }
pub type CompileFunc = Rc<dyn Fn(BoundNode, &[StaticType]) -> Result<(Value, StaticType), String>>; pub type CompileFunc = Rc<dyn Fn(Rc<BoundNode>, &[StaticType]) -> Result<(Value, StaticType), String>>;
pub type RtlLookupFunc = Rc<dyn Fn(&str, &[StaticType]) -> Option<(Value, StaticType)>>; pub type RtlLookupFunc = Rc<dyn Fn(&str, &[StaticType]) -> Option<(Value, StaticType)>>;
pub trait FunctionRegistry { pub trait FunctionRegistry {
fn resolve(&self, addr: Address) -> Option<BoundNode>; fn resolve(&self, addr: Address) -> Option<Rc<BoundNode>>;
fn resolve_analyzed(&self, _addr: Address) -> Option<AnalyzedNode> { fn resolve_analyzed(&self, _addr: Address) -> Option<Rc<AnalyzedNode>> {
None None
} }
} }
+61 -61
View File
@@ -81,11 +81,11 @@ impl TypeChecker {
pub fn check( pub fn check(
&self, &self,
node: BoundNode, node: &BoundNode,
arg_types: &[StaticType], arg_types: &[StaticType],
diag: &mut Diagnostics, diag: &mut Diagnostics,
) -> TypedNode { ) -> TypedNode {
match node.kind { match &node.kind {
BoundKind::Lambda { BoundKind::Lambda {
params, params,
upvalues, upvalues,
@@ -94,7 +94,7 @@ impl TypeChecker {
} => { } => {
// 1. Determine types of captured variables (Root lambdas have none) // 1. Determine types of captured variables (Root lambdas have none)
let mut upvalue_types = Vec::with_capacity(upvalues.len()); let mut upvalue_types = Vec::with_capacity(upvalues.len());
for _ in &upvalues { for _ in upvalues {
upvalue_types.push(StaticType::Any); upvalue_types.push(StaticType::Any);
} }
@@ -111,14 +111,14 @@ impl TypeChecker {
}; };
let params_typed = self.check_params( let params_typed = self.check_params(
params.as_ref().clone(), params.as_ref(),
&arg_tuple_ty, &arg_tuple_ty,
&mut lambda_ctx, &mut lambda_ctx,
diag, diag,
); );
// 4. Check body with the new types // 4. Check body with the new types
let body_typed = self.check_node((*body).clone(), &mut lambda_ctx, diag); let body_typed = self.check_node(body, &mut lambda_ctx, diag);
let ret_ty = body_typed.ty.clone(); let ret_ty = body_typed.ty.clone();
// 5. Construct specialized function type // 5. Construct specialized function type
@@ -130,12 +130,12 @@ impl TypeChecker {
})); }));
Node { Node {
identity: node.identity, identity: node.identity.clone(),
kind: BoundKind::Lambda { kind: BoundKind::Lambda {
params: Rc::new(params_typed), params: Rc::new(params_typed),
upvalues, upvalues: upvalues.clone(),
body: Rc::new(body_typed), body: Rc::new(body_typed),
positional_count, positional_count: *positional_count,
}, },
ty: fn_ty, ty: fn_ty,
} }
@@ -151,24 +151,24 @@ impl TypeChecker {
ty: (), ty: (),
}), }),
upvalues: vec![], upvalues: vec![],
body: Rc::new(node), body: Rc::new(node.clone()),
positional_count: Some(0), positional_count: Some(0),
}, },
ty: (), ty: (),
}; };
self.check(virtual_lambda, &[], diag) self.check(&virtual_lambda, &[], diag)
} }
} }
} }
fn check_params( fn check_params(
&self, &self,
node: BoundNode, node: &BoundNode,
specialized_ty: &StaticType, specialized_ty: &StaticType,
ctx: &mut TypeContext, ctx: &mut TypeContext,
diag: &mut Diagnostics, diag: &mut Diagnostics,
) -> TypedNode { ) -> TypedNode {
let (kind, ty) = match node.kind { let (kind, ty) = match &node.kind {
BoundKind::Define { BoundKind::Define {
name, name,
addr, addr,
@@ -176,18 +176,18 @@ impl TypeChecker {
captured_by, captured_by,
.. ..
} => { } => {
ctx.set_type(addr, specialized_ty.clone()); ctx.set_type(*addr, specialized_ty.clone());
( (
BoundKind::Define { BoundKind::Define {
name, name: name.clone(),
addr, addr: *addr,
kind: decl_kind, kind: *decl_kind,
value: Box::new(Node { value: Box::new(Node {
identity: node.identity.clone(), identity: node.identity.clone(),
kind: BoundKind::Nop, kind: BoundKind::Nop,
ty: specialized_ty.clone(), ty: specialized_ty.clone(),
}), }),
captured_by, captured_by: captured_by.clone(),
}, },
specialized_ty.clone(), specialized_ty.clone(),
) )
@@ -202,7 +202,7 @@ impl TypeChecker {
// or we could add a check here against existing type. // or we could add a check here against existing type.
( (
BoundKind::Set { BoundKind::Set {
addr, addr: *addr,
value: Box::new(Node { value: Box::new(Node {
identity: node.identity.clone(), identity: node.identity.clone(),
kind: BoundKind::Nop, kind: BoundKind::Nop,
@@ -230,7 +230,7 @@ impl TypeChecker {
Some(node.identity.clone()), Some(node.identity.clone()),
); );
return Node { return Node {
identity: node.identity, identity: node.identity.clone(),
kind: BoundKind::Error, kind: BoundKind::Error,
ty: StaticType::Error, ty: StaticType::Error,
}; };
@@ -240,11 +240,11 @@ impl TypeChecker {
let mut typed_elements = Vec::new(); let mut typed_elements = Vec::new();
let mut elem_types = Vec::new(); let mut elem_types = Vec::new();
for (i, el) in elements.into_iter().enumerate() { for (i, el) in elements.iter().enumerate() {
let sub_ty = match specialized_ty { let sub_ty = match specialized_ty {
StaticType::Tuple(t) => t.get(i).cloned().unwrap_or(StaticType::Any), StaticType::Tuple(t) => t.get(i).cloned().unwrap_or(StaticType::Any),
StaticType::Vector(inner, _) => (**inner).clone(), StaticType::Vector(inner, _) => (**inner).clone(),
StaticType::Matrix(inner, _) => (**inner).clone(), // Matrix flat iteration or row? Wait. Matrix destructuring logic is tricky. But for now let's focus on Record. StaticType::Matrix(inner, _) => (**inner).clone(),
StaticType::List(inner) => (**inner).clone(), StaticType::List(inner) => (**inner).clone(),
StaticType::Record(layout) => layout StaticType::Record(layout) => layout
.fields .fields
@@ -276,7 +276,7 @@ impl TypeChecker {
}; };
Node { Node {
identity: node.identity, identity: node.identity.clone(),
kind, kind,
ty, ty,
} }
@@ -284,16 +284,16 @@ impl TypeChecker {
fn check_node( fn check_node(
&self, &self,
node: BoundNode, node: &BoundNode,
ctx: &mut TypeContext, ctx: &mut TypeContext,
diag: &mut Diagnostics, diag: &mut Diagnostics,
) -> TypedNode { ) -> TypedNode {
let (kind, ty) = match node.kind { let (kind, ty) = match &node.kind {
BoundKind::Nop => (BoundKind::Nop, StaticType::Void), BoundKind::Nop => (BoundKind::Nop, StaticType::Void),
BoundKind::Constant(v) => { BoundKind::Constant(v) => {
let ty = v.static_type(); let ty = v.static_type();
(BoundKind::Constant(v), ty) (BoundKind::Constant(v.clone()), ty)
} }
BoundKind::Define { BoundKind::Define {
@@ -303,27 +303,27 @@ impl TypeChecker {
value, value,
captured_by, captured_by,
} => { } => {
let val_typed = self.check_node(*value, ctx, diag); let val_typed = self.check_node(value, ctx, diag);
let ty = val_typed.ty.clone(); let ty = val_typed.ty.clone();
ctx.set_type(addr, ty.clone()); ctx.set_type(*addr, ty.clone());
( (
BoundKind::Define { BoundKind::Define {
name: name.clone(), name: name.clone(),
addr, addr: *addr,
kind: decl_kind, kind: *decl_kind,
value: Box::new(val_typed), value: Box::new(val_typed),
captured_by, captured_by: captured_by.clone(),
}, },
ty, ty,
) )
} }
BoundKind::Get { addr, name } => { BoundKind::Get { addr, name } => {
let ty = ctx.get_type(addr); let ty = ctx.get_type(*addr);
( (
BoundKind::Get { BoundKind::Get {
addr, addr: *addr,
name: name.clone(), name: name.clone(),
}, },
ty, ty,
@@ -331,14 +331,14 @@ impl TypeChecker {
} }
BoundKind::FieldAccessor(k) => { BoundKind::FieldAccessor(k) => {
(BoundKind::FieldAccessor(k), StaticType::FieldAccessor(k)) (BoundKind::FieldAccessor(*k), StaticType::FieldAccessor(*k))
} }
BoundKind::GetField { rec, field } => { BoundKind::GetField { rec, field } => {
let rec_typed = self.check_node(*rec, ctx, diag); let rec_typed = self.check_node(rec, ctx, diag);
let field_ty = match &rec_typed.ty { let field_ty = match &rec_typed.ty {
StaticType::Record(layout) => { StaticType::Record(layout) => {
if let Some(idx) = layout.index_of(field) { if let Some(idx) = layout.index_of(*field) {
layout.fields[idx].1.clone() layout.fields[idx].1.clone()
} else { } else {
diag.push_error( diag.push_error(
@@ -365,20 +365,20 @@ impl TypeChecker {
( (
BoundKind::GetField { BoundKind::GetField {
rec: Box::new(rec_typed), rec: Box::new(rec_typed),
field, field: *field,
}, },
field_ty, field_ty,
) )
} }
BoundKind::Set { addr, value } => { BoundKind::Set { addr, value } => {
let val_typed = self.check_node(*value, ctx, diag); let val_typed = self.check_node(value, ctx, diag);
let ty = val_typed.ty.clone(); let ty = val_typed.ty.clone();
ctx.set_type(addr, ty.clone()); ctx.set_type(*addr, ty.clone());
( (
BoundKind::Set { BoundKind::Set {
addr, addr: *addr,
value: Box::new(val_typed), value: Box::new(val_typed),
}, },
ty, ty,
@@ -386,8 +386,8 @@ impl TypeChecker {
} }
BoundKind::Destructure { pattern, value } => { BoundKind::Destructure { pattern, value } => {
let val_typed = self.check_node(*value, ctx, diag); let val_typed = self.check_node(value, ctx, diag);
let pat_typed = self.check_params(*pattern, &val_typed.ty, ctx, diag); let pat_typed = self.check_params(pattern, &val_typed.ty, ctx, diag);
let ty = val_typed.ty.clone(); let ty = val_typed.ty.clone();
( (
BoundKind::Destructure { BoundKind::Destructure {
@@ -403,14 +403,14 @@ impl TypeChecker {
then_br, then_br,
else_br, else_br,
} => { } => {
let cond_typed = self.check_node(*cond, ctx, diag); let cond_typed = self.check_node(cond, ctx, diag);
let then_typed = self.check_node(*then_br, ctx, diag); let then_typed = self.check_node(then_br, ctx, diag);
let mut else_typed = None; let mut else_typed = None;
let mut final_ty = then_typed.ty.clone(); let mut final_ty = then_typed.ty.clone();
if let Some(e) = else_br { if let Some(e) = else_br {
let et = self.check_node(*e, ctx, diag); let et = self.check_node(e, ctx, diag);
// Basic type promotion: if types differ, fall back to Any // Basic type promotion: if types differ, fall back to Any
if et.ty != final_ty { if et.ty != final_ty {
final_ty = StaticType::Any; final_ty = StaticType::Any;
@@ -447,7 +447,7 @@ impl TypeChecker {
} }
// Specialized check for the lambda using the input types! // Specialized check for the lambda using the input types!
let typed_lambda = self.check(*lambda, &arg_types, diag); let typed_lambda = self.check(lambda, &arg_types, diag);
let ret_ty = if let StaticType::Function(sig) = &typed_lambda.ty { let ret_ty = if let StaticType::Function(sig) = &typed_lambda.ty {
// If the lambda returns an Optional(T), the pipeline filters Void and stores T! // If the lambda returns an Optional(T), the pipeline filters Void and stores T!
@@ -490,7 +490,7 @@ impl TypeChecker {
} => { } => {
// 1. Determine types of captured variables // 1. Determine types of captured variables
let mut upvalue_types = Vec::with_capacity(upvalues.len()); let mut upvalue_types = Vec::with_capacity(upvalues.len());
for &addr in &upvalues { for &addr in upvalues {
upvalue_types.push(ctx.get_type(addr)); upvalue_types.push(ctx.get_type(addr));
} }
@@ -500,7 +500,7 @@ impl TypeChecker {
// 3. Check parameters and body // 3. Check parameters and body
let params_typed = self.check_params( let params_typed = self.check_params(
params.as_ref().clone(), params.as_ref(),
&StaticType::Any, &StaticType::Any,
&mut lambda_ctx, &mut lambda_ctx,
diag, diag,
@@ -509,7 +509,7 @@ impl TypeChecker {
// Set current params type for 'again' validation // Set current params type for 'again' validation
lambda_ctx.current_params_ty = Some(params_typed.ty.clone()); lambda_ctx.current_params_ty = Some(params_typed.ty.clone());
let body_typed = self.check_node((*body).clone(), &mut lambda_ctx, diag); let body_typed = self.check_node(body, &mut lambda_ctx, diag);
let ret_ty = body_typed.ty.clone(); let ret_ty = body_typed.ty.clone();
// 4. Construct function type // 4. Construct function type
@@ -521,19 +521,19 @@ impl TypeChecker {
( (
BoundKind::Lambda { BoundKind::Lambda {
params: Rc::new(params_typed), params: Rc::new(params_typed),
upvalues, upvalues: upvalues.clone(),
body: Rc::new(body_typed), body: Rc::new(body_typed),
positional_count, positional_count: *positional_count,
}, },
fn_ty, fn_ty,
) )
} }
BoundKind::Call { callee, args } => { BoundKind::Call { callee, args } => {
let callee_typed = self.check_node(*callee, ctx, diag); let callee_typed = self.check_node(callee, ctx, diag);
// Manually check args (Tuple) to prevent Vector/Matrix promotion // Manually check args (Tuple) to prevent Vector/Matrix promotion
let args_typed = if let BoundKind::Tuple { elements } = args.kind { let args_typed = if let BoundKind::Tuple { elements } = &args.kind {
let mut typed_elements = Vec::new(); let mut typed_elements = Vec::new();
let mut elem_types = Vec::new(); let mut elem_types = Vec::new();
for e in elements { for e in elements {
@@ -542,7 +542,7 @@ impl TypeChecker {
typed_elements.push(t); typed_elements.push(t);
} }
Node { Node {
identity: args.identity, identity: args.identity.clone(),
kind: BoundKind::Tuple { kind: BoundKind::Tuple {
elements: typed_elements, elements: typed_elements,
}, },
@@ -550,7 +550,7 @@ impl TypeChecker {
} }
} else { } else {
// Should not happen as parser wraps args in Tuple, but fallback safely // Should not happen as parser wraps args in Tuple, but fallback safely
self.check_node(*args, ctx, diag) self.check_node(args, ctx, diag)
}; };
let ret_ty = match callee_typed.ty.resolve_call(&args_typed.ty) { let ret_ty = match callee_typed.ty.resolve_call(&args_typed.ty) {
@@ -578,7 +578,7 @@ impl TypeChecker {
BoundKind::Again { args } => { BoundKind::Again { args } => {
// Manually check args (Tuple) to prevent Vector/Matrix promotion // Manually check args (Tuple) to prevent Vector/Matrix promotion
let args_typed = if let BoundKind::Tuple { elements } = args.kind { let args_typed = if let BoundKind::Tuple { elements } = &args.kind {
let mut typed_elements = Vec::new(); let mut typed_elements = Vec::new();
let mut elem_types = Vec::new(); let mut elem_types = Vec::new();
for e in elements { for e in elements {
@@ -587,14 +587,14 @@ impl TypeChecker {
typed_elements.push(t); typed_elements.push(t);
} }
Node { Node {
identity: args.identity, identity: args.identity.clone(),
kind: BoundKind::Tuple { kind: BoundKind::Tuple {
elements: typed_elements, elements: typed_elements,
}, },
ty: StaticType::Tuple(elem_types), ty: StaticType::Tuple(elem_types),
} }
} else { } else {
self.check_node(*args, ctx, diag) self.check_node(args, ctx, diag)
}; };
if let Some(expected_ty) = &ctx.current_params_ty if let Some(expected_ty) = &ctx.current_params_ty
@@ -660,7 +660,7 @@ impl TypeChecker {
let mut typed_values = Vec::with_capacity(values.len()); let mut typed_values = Vec::with_capacity(values.len());
let mut fields_ty = Vec::with_capacity(values.len()); let mut fields_ty = Vec::with_capacity(values.len());
for (i, v) in values.into_iter().enumerate() { for (i, v) in values.iter().enumerate() {
let vt = self.check_node(v, ctx, diag); let vt = self.check_node(v, ctx, diag);
fields_ty.push((layout.fields[i].0, vt.ty.clone())); fields_ty.push((layout.fields[i].0, vt.ty.clone()));
typed_values.push(vt); typed_values.push(vt);
@@ -680,11 +680,11 @@ impl TypeChecker {
original_call, original_call,
bound_expanded, bound_expanded,
} => { } => {
let expanded_typed = self.check_node(*bound_expanded, ctx, diag); let expanded_typed = self.check_node(bound_expanded, ctx, diag);
let ty = expanded_typed.ty.clone(); let ty = expanded_typed.ty.clone();
( (
BoundKind::Expansion { BoundKind::Expansion {
original_call, original_call: original_call.clone(),
bound_expanded: Box::new(expanded_typed), bound_expanded: Box::new(expanded_typed),
}, },
ty, ty,
@@ -705,7 +705,7 @@ impl TypeChecker {
}; };
Node { Node {
identity: node.identity, identity: node.identity.clone(),
kind, kind,
ty, ty,
} }
+14 -11
View File
@@ -8,7 +8,10 @@ use std::cell::RefCell;
use std::collections::HashMap; use std::collections::HashMap;
use std::rc::Rc; use std::rc::Rc;
use crate::ast::compiler::bound_nodes::{Address, AnalyzedNode, BoundKind, BoundNode, GlobalIdx}; use crate::ast::compiler::bound_nodes::{
Address, AnalyzedNode, BoundKind, BoundNode, GlobalAnalyzedRegistry, GlobalFunctionRegistry,
GlobalIdx,
};
use crate::ast::compiler::dumper::Dumper; use crate::ast::compiler::dumper::Dumper;
use crate::ast::compiler::lambda_collector::LambdaCollector; use crate::ast::compiler::lambda_collector::LambdaCollector;
use crate::ast::compiler::macros::{MacroEvaluator, MacroExpander, MacroRegistry}; use crate::ast::compiler::macros::{MacroEvaluator, MacroExpander, MacroRegistry};
@@ -69,8 +72,8 @@ pub struct Environment {
pub global_types: Rc<RefCell<HashMap<GlobalIdx, StaticType>>>, pub global_types: Rc<RefCell<HashMap<GlobalIdx, StaticType>>>,
pub global_purity: Rc<RefCell<HashMap<GlobalIdx, Purity>>>, pub global_purity: Rc<RefCell<HashMap<GlobalIdx, Purity>>>,
pub global_values: Rc<RefCell<Vec<Value>>>, pub global_values: Rc<RefCell<Vec<Value>>>,
pub function_registry: Rc<RefCell<HashMap<GlobalIdx, BoundNode>>>, pub function_registry: Rc<RefCell<GlobalFunctionRegistry>>,
pub typed_function_registry: Rc<RefCell<HashMap<GlobalIdx, AnalyzedNode>>>, pub typed_function_registry: Rc<RefCell<GlobalAnalyzedRegistry>>,
pub monomorph_cache: Rc<RefCell<MonoCache>>, pub monomorph_cache: Rc<RefCell<MonoCache>>,
pub debug_mode: bool, pub debug_mode: bool,
pub optimization: bool, pub optimization: bool,
@@ -79,19 +82,19 @@ pub struct Environment {
} }
struct EnvFunctionRegistry { struct EnvFunctionRegistry {
registry: Rc<RefCell<HashMap<GlobalIdx, BoundNode>>>, registry: Rc<RefCell<GlobalFunctionRegistry>>,
analyzed_registry: Rc<RefCell<HashMap<GlobalIdx, AnalyzedNode>>>, analyzed_registry: Rc<RefCell<GlobalAnalyzedRegistry>>,
} }
impl FunctionRegistry for EnvFunctionRegistry { impl FunctionRegistry for EnvFunctionRegistry {
fn resolve(&self, addr: Address) -> Option<BoundNode> { fn resolve(&self, addr: Address) -> Option<Rc<BoundNode>> {
if let Address::Global(idx) = addr { if let Address::Global(idx) = addr {
self.registry.borrow().get(&idx).cloned() self.registry.borrow().get(&idx).cloned()
} else { } else {
None None
} }
} }
fn resolve_analyzed(&self, addr: Address) -> Option<AnalyzedNode> { fn resolve_analyzed(&self, addr: Address) -> Option<Rc<AnalyzedNode>> {
if let Address::Global(idx) = addr { if let Address::Global(idx) = addr {
self.analyzed_registry.borrow().get(&idx).cloned() self.analyzed_registry.borrow().get(&idx).cloned()
} else { } else {
@@ -122,7 +125,7 @@ impl MacroEvaluator for RuntimeMacroEvaluator {
let (bound_ast, captures) = Binder::bind_root(self.global_names.clone(), node, &mut diag)?; let (bound_ast, captures) = Binder::bind_root(self.global_names.clone(), node, &mut diag)?;
let bound_ast = crate::ast::compiler::captures::CapturePass::apply(bound_ast, &captures); let bound_ast = crate::ast::compiler::captures::CapturePass::apply(bound_ast, &captures);
let checker = TypeChecker::new(self.global_types.clone()); let checker = TypeChecker::new(self.global_types.clone());
let typed_ast = checker.check(bound_ast, &[], &mut diag); let typed_ast = checker.check(&bound_ast, &[], &mut diag);
if diag.has_errors() { if diag.has_errors() {
return Err(diag return Err(diag
@@ -316,7 +319,7 @@ impl Environment {
LambdaCollector::collect(&bound_ast, &mut self.function_registry.borrow_mut()); LambdaCollector::collect(&bound_ast, &mut self.function_registry.borrow_mut());
let checker = TypeChecker::new(self.global_types.clone()); let checker = TypeChecker::new(self.global_types.clone());
let typed_ast = checker.check(bound_ast, &[], &mut diagnostics); let typed_ast = checker.check(&bound_ast, &[], &mut diagnostics);
CompilationResult { CompilationResult {
ast: Some(typed_ast), ast: Some(typed_ast),
@@ -420,12 +423,12 @@ impl Environment {
let optimization = self.optimization; let optimization = self.optimization;
let compiler = Rc::new( let compiler = Rc::new(
move |func_template: BoundNode, move |func_template: Rc<BoundNode>,
arg_types: &[StaticType]| arg_types: &[StaticType]|
-> Result<(Value, StaticType), String> { -> Result<(Value, StaticType), String> {
let mut diag = Diagnostics::new(); let mut diag = Diagnostics::new();
let checker = TypeChecker::new(global_types.clone()); let checker = TypeChecker::new(global_types.clone());
let retyped_ast = checker.check(func_template, arg_types, &mut diag); let retyped_ast = checker.check(func_template.as_ref(), arg_types, &mut diag);
if diag.has_errors() { if diag.has_errors() {
return Err(diag return Err(diag