lumen_compiler/compiler/
regalloc.rs1use std::collections::HashMap;
5
6#[derive(Debug)]
8pub struct RegAlloc {
9 next_reg: u8,
10 bindings: HashMap<String, u8>,
11}
12
13impl Default for RegAlloc {
14 fn default() -> Self {
15 Self::new()
16 }
17}
18
19impl RegAlloc {
20 pub fn new() -> Self {
21 Self {
22 next_reg: 0,
23 bindings: HashMap::new(),
24 }
25 }
26
27 pub fn alloc_named(&mut self, name: &str) -> u8 {
29 let reg = self.next_reg;
30 self.bindings.insert(name.to_string(), reg);
31 self.next_reg += 1;
32 reg
33 }
34
35 pub fn alloc_temp(&mut self) -> u8 {
37 let reg = self.next_reg;
38 self.next_reg += 1;
39 reg
40 }
41
42 pub fn lookup(&self, name: &str) -> Option<u8> {
44 self.bindings.get(name).copied()
45 }
46
47 pub fn max_regs(&self) -> u8 {
49 self.next_reg
50 }
51
52 pub fn bind(&mut self, name: &str, reg: u8) {
54 self.bindings.insert(name.to_string(), reg);
55 }
56
57 pub fn unbind(&mut self, name: &str) {
59 self.bindings.remove(name);
60 }
61}
62
63#[cfg(test)]
64mod tests {
65 use super::*;
66
67 #[test]
68 fn test_regalloc_basic() {
69 let mut ra = RegAlloc::new();
70 let r0 = ra.alloc_named("x");
71 let r1 = ra.alloc_named("y");
72 let r2 = ra.alloc_temp();
73 assert_eq!(r0, 0);
74 assert_eq!(r1, 1);
75 assert_eq!(r2, 2);
76 assert_eq!(ra.lookup("x"), Some(0));
77 assert_eq!(ra.lookup("y"), Some(1));
78 assert_eq!(ra.max_regs(), 3);
79 }
80}