1#![allow(clippy::mut_from_ref)]
2use crate::{token::Token, tree::RuleNode};
3
4#[derive(Debug)]
5pub struct Arena {
6 tokens: bumpalo::Bump,
7 contexts: bumpalo::Bump,
8 payloads: bumpalo::Bump,
9}
10
11impl Arena {
12 pub fn with<F, R>(f: F) -> R
16 where
17 F: for<'a> FnOnce(&'a Arena) -> R,
18 {
19 let arena = Arena::new();
20 f(&arena)
21 }
22
23 pub(crate) fn new() -> Self {
24 Self {
25 tokens: bumpalo::Bump::new(),
26 contexts: bumpalo::Bump::new(),
27 payloads: bumpalo::Bump::new(),
28 }
29 }
30
31 pub(crate) fn children_arena(&self) -> &bumpalo::Bump {
32 &self.payloads
33 }
34
35 pub fn alloc_token<T>(&self, value: T) -> &mut T
36 where
37 T: Token,
38 {
39 self.tokens.alloc(value)
40 }
41
42 pub fn alloc_context<'input, 'a, T>(&'a self, value: T) -> &'a mut T
43 where
44 'input: 'a,
45 T: RuleNode<'input, 'a>,
46 {
47 let res = self.contexts.alloc(value);
48 let self_ref: *const T = res;
49 unsafe {
50 res.set_self_ref(self_ref);
51 }
52 res
53 }
54
55 pub fn alloc_exception<'a, T>(&'a self, value: T) -> bumpalo::boxed::Box<'a, T> {
56 bumpalo::boxed::Box::new_in(value, &self.payloads)
57 }
58
59 pub fn alloc_payload<T>(&self, value: T) -> &mut T {
60 self.payloads.alloc(value)
61 }
62
63 pub fn alloc<T>(&self, value: T) -> &mut T {
64 self.payloads.alloc(value)
65 }
66}