roussillon_memory/
stack.rs

1use 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}