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:
@@ -60,6 +60,9 @@ pub type BoundNode<T = ()> = Node<BoundKind<T>, T>;
|
||||
/// Type alias for a node that has been fully type-checked.
|
||||
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.
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub struct NodeMetrics {
|
||||
@@ -71,6 +74,9 @@ pub struct NodeMetrics {
|
||||
/// Type alias for a node that has been analyzed.
|
||||
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)]
|
||||
pub enum BoundKind<T = ()> {
|
||||
Nop,
|
||||
|
||||
@@ -1,15 +1,16 @@
|
||||
use crate::ast::compiler::bound_nodes::{Address, BoundKind, BoundNode, GlobalIdx};
|
||||
use std::collections::HashMap;
|
||||
use std::rc::Rc;
|
||||
|
||||
/// 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.
|
||||
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> {
|
||||
/// 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 };
|
||||
collector.visit(node);
|
||||
}
|
||||
@@ -32,7 +33,7 @@ impl<'a, T: Clone> LambdaCollector<'a, T> {
|
||||
|
||||
if let BoundKind::Lambda { .. } = ¤t.kind {
|
||||
self.registry
|
||||
.insert(*global_index, (*current).as_ref().clone());
|
||||
.insert(*global_index, Rc::new((**current).clone()));
|
||||
}
|
||||
}
|
||||
self.visit(value);
|
||||
@@ -48,7 +49,7 @@ impl<'a, T: Clone> LambdaCollector<'a, T> {
|
||||
|
||||
if let BoundKind::Lambda { .. } = ¤t.kind {
|
||||
self.registry
|
||||
.insert(*global_index, (*current).as_ref().clone());
|
||||
.insert(*global_index, Rc::new((**current).clone()));
|
||||
}
|
||||
}
|
||||
self.visit(value);
|
||||
|
||||
@@ -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::types::{Purity, Value};
|
||||
use crate::ast::vm::Closure;
|
||||
@@ -16,7 +18,7 @@ pub struct Optimizer {
|
||||
max_passes: usize,
|
||||
pub globals: Option<Rc<RefCell<Vec<Value>>>>,
|
||||
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 {
|
||||
@@ -42,7 +44,7 @@ impl Optimizer {
|
||||
|
||||
pub fn with_registry(
|
||||
mut self,
|
||||
registry: Rc<RefCell<HashMap<GlobalIdx, AnalyzedNode>>>,
|
||||
registry: Rc<RefCell<GlobalAnalyzedRegistry>>,
|
||||
) -> Self {
|
||||
self.lambda_registry = Some(registry);
|
||||
self
|
||||
|
||||
@@ -11,12 +11,12 @@ pub struct MonoCacheKey {
|
||||
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 trait FunctionRegistry {
|
||||
fn resolve(&self, addr: Address) -> Option<BoundNode>;
|
||||
fn resolve_analyzed(&self, _addr: Address) -> Option<AnalyzedNode> {
|
||||
fn resolve(&self, addr: Address) -> Option<Rc<BoundNode>>;
|
||||
fn resolve_analyzed(&self, _addr: Address) -> Option<Rc<AnalyzedNode>> {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
@@ -81,11 +81,11 @@ impl TypeChecker {
|
||||
|
||||
pub fn check(
|
||||
&self,
|
||||
node: BoundNode,
|
||||
node: &BoundNode,
|
||||
arg_types: &[StaticType],
|
||||
diag: &mut Diagnostics,
|
||||
) -> TypedNode {
|
||||
match node.kind {
|
||||
match &node.kind {
|
||||
BoundKind::Lambda {
|
||||
params,
|
||||
upvalues,
|
||||
@@ -94,7 +94,7 @@ impl TypeChecker {
|
||||
} => {
|
||||
// 1. Determine types of captured variables (Root lambdas have none)
|
||||
let mut upvalue_types = Vec::with_capacity(upvalues.len());
|
||||
for _ in &upvalues {
|
||||
for _ in upvalues {
|
||||
upvalue_types.push(StaticType::Any);
|
||||
}
|
||||
|
||||
@@ -111,14 +111,14 @@ impl TypeChecker {
|
||||
};
|
||||
|
||||
let params_typed = self.check_params(
|
||||
params.as_ref().clone(),
|
||||
params.as_ref(),
|
||||
&arg_tuple_ty,
|
||||
&mut lambda_ctx,
|
||||
diag,
|
||||
);
|
||||
|
||||
// 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();
|
||||
|
||||
// 5. Construct specialized function type
|
||||
@@ -130,12 +130,12 @@ impl TypeChecker {
|
||||
}));
|
||||
|
||||
Node {
|
||||
identity: node.identity,
|
||||
identity: node.identity.clone(),
|
||||
kind: BoundKind::Lambda {
|
||||
params: Rc::new(params_typed),
|
||||
upvalues,
|
||||
upvalues: upvalues.clone(),
|
||||
body: Rc::new(body_typed),
|
||||
positional_count,
|
||||
positional_count: *positional_count,
|
||||
},
|
||||
ty: fn_ty,
|
||||
}
|
||||
@@ -151,24 +151,24 @@ impl TypeChecker {
|
||||
ty: (),
|
||||
}),
|
||||
upvalues: vec![],
|
||||
body: Rc::new(node),
|
||||
body: Rc::new(node.clone()),
|
||||
positional_count: Some(0),
|
||||
},
|
||||
ty: (),
|
||||
};
|
||||
self.check(virtual_lambda, &[], diag)
|
||||
self.check(&virtual_lambda, &[], diag)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn check_params(
|
||||
&self,
|
||||
node: BoundNode,
|
||||
node: &BoundNode,
|
||||
specialized_ty: &StaticType,
|
||||
ctx: &mut TypeContext,
|
||||
diag: &mut Diagnostics,
|
||||
) -> TypedNode {
|
||||
let (kind, ty) = match node.kind {
|
||||
let (kind, ty) = match &node.kind {
|
||||
BoundKind::Define {
|
||||
name,
|
||||
addr,
|
||||
@@ -176,18 +176,18 @@ impl TypeChecker {
|
||||
captured_by,
|
||||
..
|
||||
} => {
|
||||
ctx.set_type(addr, specialized_ty.clone());
|
||||
ctx.set_type(*addr, specialized_ty.clone());
|
||||
(
|
||||
BoundKind::Define {
|
||||
name,
|
||||
addr,
|
||||
kind: decl_kind,
|
||||
name: name.clone(),
|
||||
addr: *addr,
|
||||
kind: *decl_kind,
|
||||
value: Box::new(Node {
|
||||
identity: node.identity.clone(),
|
||||
kind: BoundKind::Nop,
|
||||
ty: specialized_ty.clone(),
|
||||
}),
|
||||
captured_by,
|
||||
captured_by: captured_by.clone(),
|
||||
},
|
||||
specialized_ty.clone(),
|
||||
)
|
||||
@@ -202,7 +202,7 @@ impl TypeChecker {
|
||||
// or we could add a check here against existing type.
|
||||
(
|
||||
BoundKind::Set {
|
||||
addr,
|
||||
addr: *addr,
|
||||
value: Box::new(Node {
|
||||
identity: node.identity.clone(),
|
||||
kind: BoundKind::Nop,
|
||||
@@ -230,7 +230,7 @@ impl TypeChecker {
|
||||
Some(node.identity.clone()),
|
||||
);
|
||||
return Node {
|
||||
identity: node.identity,
|
||||
identity: node.identity.clone(),
|
||||
kind: BoundKind::Error,
|
||||
ty: StaticType::Error,
|
||||
};
|
||||
@@ -240,11 +240,11 @@ impl TypeChecker {
|
||||
let mut typed_elements = 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 {
|
||||
StaticType::Tuple(t) => t.get(i).cloned().unwrap_or(StaticType::Any),
|
||||
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::Record(layout) => layout
|
||||
.fields
|
||||
@@ -276,7 +276,7 @@ impl TypeChecker {
|
||||
};
|
||||
|
||||
Node {
|
||||
identity: node.identity,
|
||||
identity: node.identity.clone(),
|
||||
kind,
|
||||
ty,
|
||||
}
|
||||
@@ -284,16 +284,16 @@ impl TypeChecker {
|
||||
|
||||
fn check_node(
|
||||
&self,
|
||||
node: BoundNode,
|
||||
node: &BoundNode,
|
||||
ctx: &mut TypeContext,
|
||||
diag: &mut Diagnostics,
|
||||
) -> TypedNode {
|
||||
let (kind, ty) = match node.kind {
|
||||
let (kind, ty) = match &node.kind {
|
||||
BoundKind::Nop => (BoundKind::Nop, StaticType::Void),
|
||||
|
||||
BoundKind::Constant(v) => {
|
||||
let ty = v.static_type();
|
||||
(BoundKind::Constant(v), ty)
|
||||
(BoundKind::Constant(v.clone()), ty)
|
||||
}
|
||||
|
||||
BoundKind::Define {
|
||||
@@ -303,27 +303,27 @@ impl TypeChecker {
|
||||
value,
|
||||
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();
|
||||
ctx.set_type(addr, ty.clone());
|
||||
ctx.set_type(*addr, ty.clone());
|
||||
|
||||
(
|
||||
BoundKind::Define {
|
||||
name: name.clone(),
|
||||
addr,
|
||||
kind: decl_kind,
|
||||
addr: *addr,
|
||||
kind: *decl_kind,
|
||||
value: Box::new(val_typed),
|
||||
captured_by,
|
||||
captured_by: captured_by.clone(),
|
||||
},
|
||||
ty,
|
||||
)
|
||||
}
|
||||
|
||||
BoundKind::Get { addr, name } => {
|
||||
let ty = ctx.get_type(addr);
|
||||
let ty = ctx.get_type(*addr);
|
||||
(
|
||||
BoundKind::Get {
|
||||
addr,
|
||||
addr: *addr,
|
||||
name: name.clone(),
|
||||
},
|
||||
ty,
|
||||
@@ -331,14 +331,14 @@ impl TypeChecker {
|
||||
}
|
||||
|
||||
BoundKind::FieldAccessor(k) => {
|
||||
(BoundKind::FieldAccessor(k), StaticType::FieldAccessor(k))
|
||||
(BoundKind::FieldAccessor(*k), StaticType::FieldAccessor(*k))
|
||||
}
|
||||
|
||||
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 {
|
||||
StaticType::Record(layout) => {
|
||||
if let Some(idx) = layout.index_of(field) {
|
||||
if let Some(idx) = layout.index_of(*field) {
|
||||
layout.fields[idx].1.clone()
|
||||
} else {
|
||||
diag.push_error(
|
||||
@@ -365,20 +365,20 @@ impl TypeChecker {
|
||||
(
|
||||
BoundKind::GetField {
|
||||
rec: Box::new(rec_typed),
|
||||
field,
|
||||
field: *field,
|
||||
},
|
||||
field_ty,
|
||||
)
|
||||
}
|
||||
|
||||
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();
|
||||
ctx.set_type(addr, ty.clone());
|
||||
ctx.set_type(*addr, ty.clone());
|
||||
|
||||
(
|
||||
BoundKind::Set {
|
||||
addr,
|
||||
addr: *addr,
|
||||
value: Box::new(val_typed),
|
||||
},
|
||||
ty,
|
||||
@@ -386,8 +386,8 @@ impl TypeChecker {
|
||||
}
|
||||
|
||||
BoundKind::Destructure { pattern, value } => {
|
||||
let val_typed = self.check_node(*value, ctx, diag);
|
||||
let pat_typed = self.check_params(*pattern, &val_typed.ty, ctx, diag);
|
||||
let val_typed = self.check_node(value, ctx, diag);
|
||||
let pat_typed = self.check_params(pattern, &val_typed.ty, ctx, diag);
|
||||
let ty = val_typed.ty.clone();
|
||||
(
|
||||
BoundKind::Destructure {
|
||||
@@ -403,14 +403,14 @@ impl TypeChecker {
|
||||
then_br,
|
||||
else_br,
|
||||
} => {
|
||||
let cond_typed = self.check_node(*cond, ctx, diag);
|
||||
let then_typed = self.check_node(*then_br, ctx, diag);
|
||||
let cond_typed = self.check_node(cond, ctx, diag);
|
||||
let then_typed = self.check_node(then_br, ctx, diag);
|
||||
|
||||
let mut else_typed = None;
|
||||
let mut final_ty = then_typed.ty.clone();
|
||||
|
||||
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
|
||||
if et.ty != final_ty {
|
||||
final_ty = StaticType::Any;
|
||||
@@ -447,7 +447,7 @@ impl TypeChecker {
|
||||
}
|
||||
|
||||
// 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 {
|
||||
// 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
|
||||
let mut upvalue_types = Vec::with_capacity(upvalues.len());
|
||||
for &addr in &upvalues {
|
||||
for &addr in upvalues {
|
||||
upvalue_types.push(ctx.get_type(addr));
|
||||
}
|
||||
|
||||
@@ -500,7 +500,7 @@ impl TypeChecker {
|
||||
|
||||
// 3. Check parameters and body
|
||||
let params_typed = self.check_params(
|
||||
params.as_ref().clone(),
|
||||
params.as_ref(),
|
||||
&StaticType::Any,
|
||||
&mut lambda_ctx,
|
||||
diag,
|
||||
@@ -509,7 +509,7 @@ impl TypeChecker {
|
||||
// Set current params type for 'again' validation
|
||||
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();
|
||||
|
||||
// 4. Construct function type
|
||||
@@ -521,19 +521,19 @@ impl TypeChecker {
|
||||
(
|
||||
BoundKind::Lambda {
|
||||
params: Rc::new(params_typed),
|
||||
upvalues,
|
||||
upvalues: upvalues.clone(),
|
||||
body: Rc::new(body_typed),
|
||||
positional_count,
|
||||
positional_count: *positional_count,
|
||||
},
|
||||
fn_ty,
|
||||
)
|
||||
}
|
||||
|
||||
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
|
||||
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 elem_types = Vec::new();
|
||||
for e in elements {
|
||||
@@ -542,7 +542,7 @@ impl TypeChecker {
|
||||
typed_elements.push(t);
|
||||
}
|
||||
Node {
|
||||
identity: args.identity,
|
||||
identity: args.identity.clone(),
|
||||
kind: BoundKind::Tuple {
|
||||
elements: typed_elements,
|
||||
},
|
||||
@@ -550,7 +550,7 @@ impl TypeChecker {
|
||||
}
|
||||
} else {
|
||||
// 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) {
|
||||
@@ -578,7 +578,7 @@ impl TypeChecker {
|
||||
|
||||
BoundKind::Again { args } => {
|
||||
// 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 elem_types = Vec::new();
|
||||
for e in elements {
|
||||
@@ -587,14 +587,14 @@ impl TypeChecker {
|
||||
typed_elements.push(t);
|
||||
}
|
||||
Node {
|
||||
identity: args.identity,
|
||||
identity: args.identity.clone(),
|
||||
kind: BoundKind::Tuple {
|
||||
elements: typed_elements,
|
||||
},
|
||||
ty: StaticType::Tuple(elem_types),
|
||||
}
|
||||
} else {
|
||||
self.check_node(*args, ctx, diag)
|
||||
self.check_node(args, ctx, diag)
|
||||
};
|
||||
|
||||
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 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);
|
||||
fields_ty.push((layout.fields[i].0, vt.ty.clone()));
|
||||
typed_values.push(vt);
|
||||
@@ -680,11 +680,11 @@ impl TypeChecker {
|
||||
original_call,
|
||||
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();
|
||||
(
|
||||
BoundKind::Expansion {
|
||||
original_call,
|
||||
original_call: original_call.clone(),
|
||||
bound_expanded: Box::new(expanded_typed),
|
||||
},
|
||||
ty,
|
||||
@@ -705,7 +705,7 @@ impl TypeChecker {
|
||||
};
|
||||
|
||||
Node {
|
||||
identity: node.identity,
|
||||
identity: node.identity.clone(),
|
||||
kind,
|
||||
ty,
|
||||
}
|
||||
|
||||
+14
-11
@@ -8,7 +8,10 @@ use std::cell::RefCell;
|
||||
use std::collections::HashMap;
|
||||
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::lambda_collector::LambdaCollector;
|
||||
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_purity: Rc<RefCell<HashMap<GlobalIdx, Purity>>>,
|
||||
pub global_values: Rc<RefCell<Vec<Value>>>,
|
||||
pub function_registry: Rc<RefCell<HashMap<GlobalIdx, BoundNode>>>,
|
||||
pub typed_function_registry: Rc<RefCell<HashMap<GlobalIdx, AnalyzedNode>>>,
|
||||
pub function_registry: Rc<RefCell<GlobalFunctionRegistry>>,
|
||||
pub typed_function_registry: Rc<RefCell<GlobalAnalyzedRegistry>>,
|
||||
pub monomorph_cache: Rc<RefCell<MonoCache>>,
|
||||
pub debug_mode: bool,
|
||||
pub optimization: bool,
|
||||
@@ -79,19 +82,19 @@ pub struct Environment {
|
||||
}
|
||||
|
||||
struct EnvFunctionRegistry {
|
||||
registry: Rc<RefCell<HashMap<GlobalIdx, BoundNode>>>,
|
||||
analyzed_registry: Rc<RefCell<HashMap<GlobalIdx, AnalyzedNode>>>,
|
||||
registry: Rc<RefCell<GlobalFunctionRegistry>>,
|
||||
analyzed_registry: Rc<RefCell<GlobalAnalyzedRegistry>>,
|
||||
}
|
||||
|
||||
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 {
|
||||
self.registry.borrow().get(&idx).cloned()
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
fn resolve_analyzed(&self, addr: Address) -> Option<AnalyzedNode> {
|
||||
fn resolve_analyzed(&self, addr: Address) -> Option<Rc<AnalyzedNode>> {
|
||||
if let Address::Global(idx) = addr {
|
||||
self.analyzed_registry.borrow().get(&idx).cloned()
|
||||
} 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 = crate::ast::compiler::captures::CapturePass::apply(bound_ast, &captures);
|
||||
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() {
|
||||
return Err(diag
|
||||
@@ -316,7 +319,7 @@ impl Environment {
|
||||
LambdaCollector::collect(&bound_ast, &mut self.function_registry.borrow_mut());
|
||||
|
||||
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 {
|
||||
ast: Some(typed_ast),
|
||||
@@ -420,12 +423,12 @@ impl Environment {
|
||||
let optimization = self.optimization;
|
||||
|
||||
let compiler = Rc::new(
|
||||
move |func_template: BoundNode,
|
||||
move |func_template: Rc<BoundNode>,
|
||||
arg_types: &[StaticType]|
|
||||
-> Result<(Value, StaticType), String> {
|
||||
let mut diag = Diagnostics::new();
|
||||
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() {
|
||||
return Err(diag
|
||||
|
||||
Reference in New Issue
Block a user