roussillon_memory/
stack.rs1use std::cell::RefCell;
2use std::rc::Rc;
3use roussillon_type_system::types::concept::{DataType, Type};
4use roussillon_type_system::value::concept::{DataValue, ValueCell};
5use roussillon_type_system::value::error::TypeResult;
6use roussillon_type_system::value::reference::Reference;
7
8use crate::region::{Allocator, Dereference, Region};
9
10pub struct StackReferenceType {
11 t: Type,
12}
13
14impl StackReferenceType {
15 pub fn to_rc(self) -> Rc<Self> { Rc::new(self) }
16}
17
18impl DataType for StackReferenceType {
19 fn size(&self) -> usize {
20 16
21 }
22
23 fn typename(&self) -> String {
24 format!("$&{}", self.t)
25 }
26
27 fn construct_from_raw(&self, raw: &[u8]) -> TypeResult<ValueCell> {
28 let (raw_generation, raw_reference) = raw.split_at(8);
29 let level = usize::from_be_bytes(raw_generation.try_into().unwrap());
30 let raw_reference = usize::from_be_bytes(raw_reference.try_into().unwrap());
31 let reference = Reference::new(self.t.clone(), raw_reference);
32 Ok(StackReference { level, reference }.to_cell())
33 }
34}
35
36#[derive(Clone, Debug)]
37pub struct StackReference {
38 level: usize,
39 reference: Reference,
40}
41
42impl StackReference {
43 pub fn reference(&self) -> &Reference {
44 &self.reference
45 }
46 pub fn to_cell(self) -> ValueCell { Rc::new(RefCell::new(self)) }
47}
48
49impl DataValue for StackReference {
50 fn data_type(&self) -> Type {
51 StackReferenceType { t: self.reference.data_type() }.to_rc()
52 }
53
54 fn raw(&self) -> Vec<u8> {
55 let mut raw = Vec::new();
56 raw.extend_from_slice(&self.level.to_be_bytes());
57 raw.extend_from_slice(&self.reference.raw());
58 raw
59 }
60
61 fn set(&mut self, raw: &[u8]) {
62 let (raw_level, raw_reference) = raw.split_at(8);
63 self.level = usize::from_be_bytes(raw_level.try_into().unwrap());
64 let raw_reference = usize::from_be_bytes(raw_reference.try_into().unwrap());
65 self.reference = Reference::new(self.reference.referenced().clone(), raw_reference);
66 }
67}
68
69#[derive(Default, Debug)]
70pub struct Stack {
71 raw: Vec<Region>,
72}
73
74impl Stack {
75 pub fn new() -> Self { Stack { raw: Vec::new() } }
76
77 pub fn push(&mut self, region: Region) {
78 self.raw.push(region)
79 }
80 pub fn pop(&mut self) -> Option<Region> {
81 self.raw.pop()
82 }
83}
84
85impl Allocator<StackReference> for Stack {
86 fn allocate(&mut self, cell: ValueCell) -> StackReference {
87 let mut current = self.pop().unwrap();
88 let level = self.raw.len();
89 let reference = current.allocate(cell);
90 self.push(current);
91 StackReference { level, reference }
92 }
93}
94
95impl Dereference<StackReference> for Stack {
96 fn dereference(&self, reference: StackReference) -> Option<ValueCell> {
97 if reference.level >= self.raw.len() {
98 None
99 } else {
100 self.raw[reference.level].dereference(reference.reference)
101 }
102 }
103
104 fn validate(&self, reference: &StackReference) -> bool {
105 reference.level < self.raw.len()
106 }
107}