Refactor bound node types for clarity
Introduce generic `CompilerPhase` trait to unify different stages of the bound AST. Rename `LocalSlot` to `VirtualId` and introduce `StackOffset` for clearer distinction between compile-time and run-time addressing. Update type aliases and implementations to reflect these changes.
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
use crate::ast::compiler::bound_nodes::{Address, AnalyzedNode, BoundKind, LocalSlot};
|
||||
use crate::ast::compiler::bound_nodes::{Address, AnalyzedNode, BoundKind, VirtualId};
|
||||
use crate::ast::types::{Purity, Value};
|
||||
use crate::ast::vm::Closure;
|
||||
use std::cell::RefCell;
|
||||
@@ -24,7 +24,7 @@ impl<'a> Inliner<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_inlinable_value(&self, val: &Value, addr: Address) -> bool {
|
||||
pub fn is_inlinable_value(&self, val: &Value, addr: Address<VirtualId>) -> bool {
|
||||
let type_ok = match val {
|
||||
Value::Int(_)
|
||||
| Value::Float(_)
|
||||
@@ -141,7 +141,7 @@ impl<'a> Inliner<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn collect_parameter_slots_set(&self, node: &AnalyzedNode, slots: &mut HashSet<LocalSlot>) {
|
||||
pub fn collect_parameter_slots_set(&self, node: &AnalyzedNode, slots: &mut HashSet<VirtualId>) {
|
||||
match &node.kind {
|
||||
BoundKind::Define {
|
||||
addr: Address::Local(slot),
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
use crate::ast::compiler::bound_nodes::{Address, AnalyzedNode, BoundKind, LocalSlot, Node, UpvalueIdx};
|
||||
use crate::ast::compiler::bound_nodes::{Address, AnalyzedNode, BoundKind, Node, UpvalueIdx, VirtualId};
|
||||
use crate::ast::types::Value;
|
||||
use std::collections::{HashMap, HashSet};
|
||||
use std::rc::Rc;
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct SubstitutionMap {
|
||||
pub values: HashMap<Address, Value>,
|
||||
pub ast_substitutions: HashMap<Address, Rc<AnalyzedNode>>,
|
||||
pub slot_mapping: HashMap<LocalSlot, LocalSlot>,
|
||||
pub assigned: HashSet<Address>,
|
||||
pub values: HashMap<Address<VirtualId>, Value>,
|
||||
pub ast_substitutions: HashMap<Address<VirtualId>, Rc<AnalyzedNode>>,
|
||||
pub slot_mapping: HashMap<VirtualId, VirtualId>,
|
||||
pub assigned: HashSet<Address<VirtualId>>,
|
||||
pub next_slot: u32,
|
||||
pub used: HashSet<Address>,
|
||||
pub captured_slots: HashSet<LocalSlot>,
|
||||
pub used: HashSet<Address<VirtualId>>,
|
||||
pub captured_slots: HashSet<VirtualId>,
|
||||
}
|
||||
|
||||
impl SubstitutionMap {
|
||||
@@ -43,40 +43,40 @@ impl SubstitutionMap {
|
||||
inner
|
||||
}
|
||||
|
||||
pub fn add_ast_substitution(&mut self, addr: Address, node: AnalyzedNode) {
|
||||
pub fn add_ast_substitution(&mut self, addr: Address<VirtualId>, node: AnalyzedNode) {
|
||||
self.ast_substitutions.insert(addr, Rc::new(node));
|
||||
}
|
||||
|
||||
pub fn map_slot(&mut self, old_slot: LocalSlot) -> LocalSlot {
|
||||
pub fn map_slot(&mut self, old_slot: VirtualId) -> VirtualId {
|
||||
if let Some(&new_slot) = self.slot_mapping.get(&old_slot) {
|
||||
return new_slot;
|
||||
}
|
||||
let new_slot = LocalSlot(self.next_slot);
|
||||
let new_slot = VirtualId(self.next_slot);
|
||||
self.slot_mapping.insert(old_slot, new_slot);
|
||||
self.next_slot += 1;
|
||||
new_slot
|
||||
}
|
||||
|
||||
pub fn map_address(&mut self, addr: Address) -> Address {
|
||||
pub fn map_address(&mut self, addr: Address<VirtualId>) -> Address<VirtualId> {
|
||||
match addr {
|
||||
Address::Local(slot) => Address::Local(self.map_slot(slot)),
|
||||
other => other,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn add_value(&mut self, addr: Address, val: Value) {
|
||||
pub fn add_value(&mut self, addr: Address<VirtualId>, val: Value) {
|
||||
self.values.insert(addr, val);
|
||||
}
|
||||
|
||||
pub fn get_value(&self, addr: &Address) -> Option<&Value> {
|
||||
pub fn get_value(&self, addr: &Address<VirtualId>) -> Option<&Value> {
|
||||
self.values.get(addr)
|
||||
}
|
||||
|
||||
pub fn remove_value(&mut self, addr: &Address) {
|
||||
pub fn remove_value(&mut self, addr: &Address<VirtualId>) {
|
||||
self.values.remove(addr);
|
||||
}
|
||||
|
||||
fn reindex_addr(&self, addr: Address, mapping: &[Option<u32>]) -> Address {
|
||||
fn reindex_addr(&self, addr: Address<VirtualId>, mapping: &[Option<u32>]) -> Address<VirtualId> {
|
||||
if let Address::Upvalue(idx) = addr
|
||||
&& let Some(res) = mapping.get(idx.0 as usize)
|
||||
&& let Some(new_idx) = res
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use crate::ast::compiler::bound_nodes::{Address, AnalyzedNode, BoundKind, GlobalIdx};
|
||||
use crate::ast::compiler::bound_nodes::{Address, AnalyzedNode, BoundKind, GlobalIdx, VirtualId};
|
||||
use crate::ast::types::{Identity, Value};
|
||||
use crate::ast::vm::Closure;
|
||||
use std::collections::HashSet;
|
||||
@@ -32,17 +32,17 @@ impl PathTracker {
|
||||
// --- UsageInfo ---
|
||||
#[derive(Default)]
|
||||
pub struct UsageInfo {
|
||||
pub used: HashSet<Address>,
|
||||
pub assigned: HashSet<Address>,
|
||||
pub used: HashSet<Address<VirtualId>>,
|
||||
pub assigned: HashSet<Address<VirtualId>>,
|
||||
pub used_identities: HashSet<Identity>,
|
||||
}
|
||||
|
||||
impl UsageInfo {
|
||||
pub fn is_assigned(&self, addr: &Address) -> bool {
|
||||
pub fn is_assigned(&self, addr: &Address<VirtualId>) -> bool {
|
||||
self.assigned.contains(addr)
|
||||
}
|
||||
|
||||
pub fn is_used(&self, addr: &Address) -> bool {
|
||||
pub fn is_used(&self, addr: &Address<VirtualId>) -> bool {
|
||||
self.used.contains(addr)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user