Refactor TypeContext locals to HashMap
Change the `slots` field in `TypeContext` from a `Vec` to a `HashMap`. This allows for sparse local variable storage and avoids the need to pre-allocate for all slots, which is more efficient when not all locals are used.
This commit is contained in:
@@ -1,13 +1,14 @@
|
|||||||
use crate::ast::compiler::bound_nodes::{Address, BoundKind, Node, TypedNode};
|
use crate::ast::compiler::bound_nodes::{Address, BoundKind, Node, TypedNode};
|
||||||
use crate::ast::diagnostics::Diagnostics;
|
use crate::ast::diagnostics::Diagnostics;
|
||||||
use crate::ast::types::StaticType;
|
use crate::ast::types::StaticType;
|
||||||
|
use std::collections::HashMap;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
/// Manages the types of locals and upvalues during a single type-checking pass.
|
/// Manages the types of locals and upvalues during a single type-checking pass.
|
||||||
struct TypeContext<'a> {
|
struct TypeContext<'a> {
|
||||||
_parent: Option<&'a TypeContext<'a>>,
|
_parent: Option<&'a TypeContext<'a>>,
|
||||||
/// Maps slot index -> Inferred Type
|
/// Maps slot index -> Inferred Type
|
||||||
slots: Vec<StaticType>,
|
slots: HashMap<u32, StaticType>,
|
||||||
/// Types of captured variables (passed from outer scope)
|
/// Types of captured variables (passed from outer scope)
|
||||||
upvalue_types: Vec<StaticType>,
|
upvalue_types: Vec<StaticType>,
|
||||||
/// Access to root types for unified resolution
|
/// Access to root types for unified resolution
|
||||||
@@ -18,14 +19,14 @@ struct TypeContext<'a> {
|
|||||||
|
|
||||||
impl<'a> TypeContext<'a> {
|
impl<'a> TypeContext<'a> {
|
||||||
fn new(
|
fn new(
|
||||||
slot_count: u32,
|
_slot_count: u32,
|
||||||
upvalue_types: Vec<StaticType>,
|
upvalue_types: Vec<StaticType>,
|
||||||
root_types: &'a std::cell::RefCell<Vec<StaticType>>,
|
root_types: &'a std::cell::RefCell<Vec<StaticType>>,
|
||||||
parent: Option<&'a TypeContext<'a>>,
|
parent: Option<&'a TypeContext<'a>>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
_parent: parent,
|
_parent: parent,
|
||||||
slots: vec![StaticType::Any; slot_count as usize],
|
slots: HashMap::new(),
|
||||||
upvalue_types,
|
upvalue_types,
|
||||||
root_types,
|
root_types,
|
||||||
current_params_ty: None,
|
current_params_ty: None,
|
||||||
@@ -36,7 +37,7 @@ impl<'a> TypeContext<'a> {
|
|||||||
match addr {
|
match addr {
|
||||||
Address::Local(slot) => self
|
Address::Local(slot) => self
|
||||||
.slots
|
.slots
|
||||||
.get(slot.0 as usize)
|
.get(&slot.0)
|
||||||
.cloned()
|
.cloned()
|
||||||
.unwrap_or(StaticType::Any),
|
.unwrap_or(StaticType::Any),
|
||||||
Address::Global(idx) => self
|
Address::Global(idx) => self
|
||||||
@@ -56,9 +57,7 @@ impl<'a> TypeContext<'a> {
|
|||||||
fn set_type(&mut self, addr: Address, ty: StaticType) {
|
fn set_type(&mut self, addr: Address, ty: StaticType) {
|
||||||
match addr {
|
match addr {
|
||||||
Address::Local(slot) => {
|
Address::Local(slot) => {
|
||||||
if let Some(entry) = self.slots.get_mut(slot.0 as usize) {
|
self.slots.insert(slot.0, ty);
|
||||||
*entry = ty;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Address::Global(idx) => {
|
Address::Global(idx) => {
|
||||||
let mut rt = self.root_types.borrow_mut();
|
let mut rt = self.root_types.borrow_mut();
|
||||||
|
|||||||
Reference in New Issue
Block a user