1use crate::core::adaptive::GrammarStateId;
2use crate::core::context::ParserContext;
3use crate::core::parser::Parser;
4use crate::core::pos::Pos;
5use crate::core::presult::PResult;
6use crate::core::presult::PResult::{PErr, POk};
7use crate::core::state::ParserState;
8use crate::error::error_printer::ErrorLabel;
9use crate::error::error_printer::ErrorLabel::Debug;
10use crate::error::{err_combine_opt, ParseError};
11use crate::grammar::action_result::ActionResult;
12use crate::parser::var_map::BlockCtx;
13use bumpalo::Bump;
14use bumpalo_try::BumpaloExtend;
15
16#[derive(Eq, PartialEq, Hash, Clone)]
17pub struct CacheKey {
18 pos: Pos,
19 block_state: BlockKey,
20 ctx: ParserContext,
21 state: GrammarStateId,
22}
23
24#[derive(Eq, PartialEq, Hash, Clone)]
25pub struct BlockKey(usize, usize);
26
27impl From<BlockCtx<'_, '_>> for BlockKey {
28 fn from(value: BlockCtx) -> Self {
29 BlockKey(value.0.as_ptr() as usize, value.1.as_ptr() as usize)
30 }
31}
32
33pub type CacheVal<'arn, 'grm, E> = PResult<&'arn ActionResult<'arn, 'grm>, E>;
34
35#[derive(Copy, Clone)]
36pub struct Allocs<'arn> {
37 bump: &'arn Bump,
38}
39
40impl<'arn> Allocs<'arn> {
41 pub fn new(bump: &'arn Bump) -> Self {
42 Self { bump }
43 }
44
45 pub fn new_leaking() -> Self {
46 Self {
47 bump: Box::leak(Box::new(Bump::new())),
48 }
49 }
50
51 pub fn alloc<T: Copy>(&self, t: T) -> &'arn mut T {
52 self.bump.alloc(t)
53 }
54
55 pub fn alloc_extend<T: Copy, I: IntoIterator<Item = T, IntoIter: ExactSizeIterator>>(
56 &self,
57 iter: I,
58 ) -> &'arn mut [T] {
59 self.bump.alloc_slice_fill_iter(iter)
60 }
61
62 pub fn alloc_extend_len<T: Copy, I: IntoIterator<Item = T>>(
63 &self,
64 len: usize,
65 iter: I,
66 ) -> &'arn mut [T] {
67 let mut iter = iter.into_iter();
68 let slice = self.bump.alloc_slice_fill_with(len, |_| {
69 iter.next().expect("Iterator supplied too few elements")
70 });
71 assert!(iter.next().is_none());
72 slice
73 }
74
75 pub fn try_alloc_extend<
76 T: Copy,
77 I: IntoIterator<Item = Option<T>, IntoIter: ExactSizeIterator>,
78 >(
79 &self,
80 iter: I,
81 ) -> Option<&'arn mut [T]> {
82 self.bump.alloc_slice_fill_iter_option(iter)
83 }
84}
85
86pub struct ParserCacheEntry<PR> {
87 pub read: bool,
88 pub value: PR,
89}
90
91pub fn parser_cache_recurse<'a, 'arn: 'a, 'grm: 'arn, E: ParseError<L = ErrorLabel<'grm>>>(
92 sub: &'a impl Parser<'arn, 'grm, &'arn ActionResult<'arn, 'grm>, E>,
93 block_state: BlockCtx<'arn, 'grm>,
94 grammar_state: GrammarStateId,
95) -> impl Parser<'arn, 'grm, &'arn ActionResult<'arn, 'grm>, E> + 'a {
96 move |pos_start: Pos, state: &mut ParserState<'arn, 'grm, E>, context: ParserContext| {
97 let key = CacheKey {
99 pos: pos_start,
100 block_state: block_state.into(),
101 ctx: context,
102 state: grammar_state,
103 };
104 if let Some(cached) = state.cache_get(&key) {
105 return cached.clone();
106 }
107
108 let mut res_recursive = PResult::new_err(E::new(pos_start.span_to(pos_start)), pos_start);
111 res_recursive.add_label_explicit(Debug(pos_start.span_to(pos_start), "LEFTREC"));
112
113 let cache_state = state.cache_state_get();
114 state.cache_insert(key.clone(), res_recursive);
115
116 let res = sub.parse(pos_start, state, context);
124 match res {
125 POk(mut o, mut spos, mut epos, mut be) => {
126 if !state.cache_is_read(key.clone()).unwrap() {
128 let res = POk(o, spos, epos, be);
130 state.cache_insert(key, res.clone());
131 res
132 } else {
133 loop {
135 state.cache_state_revert(cache_state);
137 state.cache_insert(key.clone(), POk(o, spos, epos, be.clone()));
138
139 let new_res = sub.parse(pos_start, state, context);
141 match new_res {
142 POk(new_o, new_spos, new_epos, new_be)
143 if new_epos.cmp(&epos).is_gt() =>
144 {
145 o = new_o;
146 spos = new_spos;
147 epos = new_epos;
148 be = new_be;
149 }
150 POk(_, _, _, new_be) => {
151 be = err_combine_opt(be, new_be);
152 break;
153 }
154 PErr(new_e, new_s) => {
155 be = err_combine_opt(be, Some((new_e, new_s)));
156 break;
157 }
158 }
159 }
160
161 POk(o, spos, epos, be)
164 }
165 }
166 res @ PErr(_, _) => {
167 state.cache_insert(key, res.clone());
168 res
169 }
170 }
171 }
172}