Files
hakorune/src/mir/join_ir/lowering/value_id_ranges.rs

159 lines
4.7 KiB
Rust
Raw Normal View History

//! ValueId Range Allocation for JoinIR Lowering Modules
//!
//! This module manages ValueId ranges for each JoinIR lowering module to prevent
//! ID conflicts when multiple lowerings coexist.
//!
//! ## Current Allocations
//!
//! | Module | Range | Entry | Loop | Notes |
//! |-----------------------|-----------|-------|-------|-------|
//! | min_loop | 1000-2999 | 1000+ | 2000+ | Minimal loop test |
//! | skip_ws | 3000-4999 | 3000+ | 4000+ | Skip whitespace |
//! | funcscanner_trim | 5000-6999 | 5000+ | 6000+ | Trim whitespace |
//! | stage1_using_resolver | 7000-8999 | 7000+ | 8000+ | Stage-1 using resolver |
//!
//! ## Usage Example
//!
//! ```rust,ignore
//! use crate::mir::join_ir::lowering::value_id_ranges::stage1_using_resolver as vid;
//!
//! let entries_param = vid::entry(0); // ValueId(7000)
//! let n_param = vid::entry(1); // ValueId(7001)
//! let entries_loop = vid::loop_step(0); // ValueId(8000)
//! let n_loop = vid::loop_step(1); // ValueId(8001)
//! ```
//!
//! ## Future Extensions
//!
//! When adding new lowering modules, allocate ranges in increments of 2000:
//! - 9000-10999 (next available)
//! - 11000-12999
//! - 13000-14999
//! - etc.
use crate::mir::ValueId;
/// Base addresses for each lowering module's ValueId range
pub mod base {
/// min_loop: Minimal loop test (1000-2999)
pub const MIN_LOOP: u32 = 1000;
/// skip_ws: Skip whitespace loop (3000-4999)
pub const SKIP_WS: u32 = 3000;
/// funcscanner_trim: Trim whitespace loop (5000-6999)
pub const FUNCSCANNER_TRIM: u32 = 5000;
/// stage1_using_resolver: Stage-1 using resolver entries loop (7000-8999)
pub const STAGE1_USING_RESOLVER: u32 = 7000;
}
/// Helper function to create ValueId from base + offset
///
/// This is a const fn, so it's computed at compile time with zero runtime cost.
#[inline]
pub const fn id(base: u32, offset: u32) -> ValueId {
ValueId(base + offset)
}
/// ValueId helpers for min_loop lowering module
pub mod min_loop {
use super::{base, id};
use crate::mir::ValueId;
/// Entry function ValueIds (1000-1999)
#[inline]
pub const fn entry(offset: u32) -> ValueId {
id(base::MIN_LOOP, offset)
}
/// Loop function ValueIds (2000-2999)
#[inline]
pub const fn loop_step(offset: u32) -> ValueId {
id(base::MIN_LOOP, 1000 + offset)
}
}
/// ValueId helpers for skip_ws lowering module
pub mod skip_ws {
use super::{base, id};
use crate::mir::ValueId;
/// Entry function ValueIds (3000-3999)
#[inline]
pub const fn entry(offset: u32) -> ValueId {
id(base::SKIP_WS, offset)
}
/// Loop function ValueIds (4000-4999)
#[inline]
pub const fn loop_step(offset: u32) -> ValueId {
id(base::SKIP_WS, 1000 + offset)
}
}
/// ValueId helpers for funcscanner_trim lowering module
pub mod funcscanner_trim {
use super::{base, id};
use crate::mir::ValueId;
/// Entry function ValueIds (5000-5999)
#[inline]
pub const fn entry(offset: u32) -> ValueId {
id(base::FUNCSCANNER_TRIM, offset)
}
/// Loop function ValueIds (6000-6999)
#[inline]
pub const fn loop_step(offset: u32) -> ValueId {
id(base::FUNCSCANNER_TRIM, 1000 + offset)
}
}
/// ValueId helpers for stage1_using_resolver lowering module
pub mod stage1_using_resolver {
use super::{base, id};
use crate::mir::ValueId;
/// Entry function ValueIds (7000-7999)
#[inline]
pub const fn entry(offset: u32) -> ValueId {
id(base::STAGE1_USING_RESOLVER, offset)
}
/// Loop function ValueIds (8000-8999)
#[inline]
pub const fn loop_step(offset: u32) -> ValueId {
id(base::STAGE1_USING_RESOLVER, 1000 + offset)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_value_id_ranges_no_overlap() {
// min_loop: 1000-2999
assert_eq!(min_loop::entry(0).0, 1000);
assert_eq!(min_loop::loop_step(999).0, 2999);
// skip_ws: 3000-4999
assert_eq!(skip_ws::entry(0).0, 3000);
assert_eq!(skip_ws::loop_step(999).0, 4999);
// funcscanner_trim: 5000-6999
assert_eq!(funcscanner_trim::entry(0).0, 5000);
assert_eq!(funcscanner_trim::loop_step(999).0, 6999);
// stage1_using_resolver: 7000-8999
assert_eq!(stage1_using_resolver::entry(0).0, 7000);
assert_eq!(stage1_using_resolver::loop_step(999).0, 8999);
// Verify no overlaps
assert!(min_loop::loop_step(999).0 < skip_ws::entry(0).0);
assert!(skip_ws::loop_step(999).0 < funcscanner_trim::entry(0).0);
assert!(funcscanner_trim::loop_step(999).0 < stage1_using_resolver::entry(0).0);
}
}