Files
@ 3ffeb97c88a7
Branch filter:
Location: CSY/reowolf/src/protocol/arena.rs - annotation
3ffeb97c88a7
2.4 KiB
application/rls-services+xml
Add docs for implementing infinite types in a value based language.
Since we are a value based language and do not have the concept of
pointers, then if we want to lay out the memory of datatypes we run
into a problem when the types represent recursive datastructures:
these are infinite in size. So we have an algorithm for turning
some types into pointer-like things, such that we can lay everything
out in memory.
Since we are a value based language and do not have the concept of
pointers, then if we want to lay out the memory of datatypes we run
into a problem when the types represent recursive datastructures:
these are infinite in size. So we have an algorithm for turning
some types into pointer-like things, such that we can lay everything
out in memory.
44a98be4e4b4 3f236d37dad1 3f236d37dad1 3f236d37dad1 3f236d37dad1 1a42eb33aa76 1a42eb33aa76 1a42eb33aa76 3f236d37dad1 3f236d37dad1 6ec2e0261a03 6ec2e0261a03 120857c65991 120857c65991 120857c65991 6ec2e0261a03 6ec2e0261a03 03af3095927d c2b16314e873 44a98be4e4b4 44a98be4e4b4 44a98be4e4b4 44a98be4e4b4 44a98be4e4b4 44a98be4e4b4 44a98be4e4b4 44a98be4e4b4 44a98be4e4b4 3f236d37dad1 3f236d37dad1 3f236d37dad1 3f236d37dad1 3f236d37dad1 3f236d37dad1 3f236d37dad1 3f236d37dad1 3f236d37dad1 3f236d37dad1 3f236d37dad1 3f236d37dad1 3f236d37dad1 3f236d37dad1 3f236d37dad1 3f236d37dad1 3f236d37dad1 33ea10021de4 3f236d37dad1 3f236d37dad1 3f236d37dad1 3f236d37dad1 1a42eb33aa76 3f236d37dad1 1a42eb33aa76 1a42eb33aa76 1a42eb33aa76 3f236d37dad1 3f236d37dad1 3f236d37dad1 1a42eb33aa76 fe0efc81bd4e fe0efc81bd4e fe0efc81bd4e fe0efc81bd4e fe0efc81bd4e fe0efc81bd4e 33ea10021de4 33ea10021de4 3f236d37dad1 1a42eb33aa76 379cffa23df8 379cffa23df8 379cffa23df8 3f236d37dad1 3f236d37dad1 3f236d37dad1 3f236d37dad1 1a42eb33aa76 3f236d37dad1 3f236d37dad1 3f236d37dad1 3f236d37dad1 3f236d37dad1 1a42eb33aa76 3f236d37dad1 3f236d37dad1 33ea10021de4 | use crate::common::*;
use core::hash::Hash;
use core::marker::PhantomData;
pub struct Id<T> {
// Not actually a signed index into the heap. But the index is set to -1 if
// we don't know an ID yet. This is checked during debug mode.
pub(crate) index: i32,
_phantom: PhantomData<T>,
}
impl<T> Id<T> {
#[inline] pub(crate) fn new_invalid() -> Self { Self{ index: -1, _phantom: Default::default() } }
#[inline] pub(crate) fn new(index: i32) -> Self { Self{ index, _phantom: Default::default() } }
#[inline] pub(crate) fn is_invalid(&self) -> bool { self.index < 0 }
}
#[derive(Debug)]
pub(crate) struct Arena<T> {
store: Vec<T>,
}
//////////////////////////////////
impl<T> Debug for Id<T> {
fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
f.debug_struct("Id").field("index", &self.index).finish()
}
}
impl<T> Clone for Id<T> {
fn clone(&self) -> Self {
*self
}
}
impl<T> Copy for Id<T> {}
impl<T> PartialEq for Id<T> {
fn eq(&self, other: &Self) -> bool {
self.index.eq(&other.index)
}
}
impl<T> Eq for Id<T> {}
impl<T> Hash for Id<T> {
fn hash<H: std::hash::Hasher>(&self, h: &mut H) {
self.index.hash(h);
}
}
impl<T> Arena<T> {
pub fn new() -> Self {
Self { store: vec![] }
}
pub fn alloc_with_id(&mut self, f: impl FnOnce(Id<T>) -> T) -> Id<T> {
// Lets keep this a runtime assert.
assert!(self.store.len() < i32::max_value() as usize, "Arena out of capacity");
let id = Id::new(self.store.len() as i32);
self.store.push(f(id));
id
}
// Compiler-internal direct retrieval
pub(crate) fn get_id(&self, idx: usize) -> Id<T> {
debug_assert!(idx < self.store.len());
return Id::new(idx as i32);
}
pub fn iter(&self) -> impl Iterator<Item = &T> {
self.store.iter()
}
pub fn len(&self) -> usize {
self.store.len()
}
}
impl<T> core::ops::Index<Id<T>> for Arena<T> {
type Output = T;
fn index(&self, id: Id<T>) -> &Self::Output {
debug_assert!(!id.is_invalid(), "attempted to index into Arena with an invalid id (index < 0)");
self.store.index(id.index as usize)
}
}
impl<T> core::ops::IndexMut<Id<T>> for Arena<T> {
fn index_mut(&mut self, id: Id<T>) -> &mut Self::Output {
debug_assert!(!id.is_invalid(), "attempted to index_mut into Arena with an invalid id (index < 0)");
self.store.index_mut(id.index as usize)
}
}
|