nickel_lang_core/eval/cache/mod.rs
1/// The Nickel generic evaluation cache. This module abstracts away the details for managing
2/// suspended computations and their memoization strategies.
3///
4/// Terminology:
5/// An *element* of the cache is what is stored inside of it.
6/// An *index* into the cache points to a given element.
7use super::{Closure, value::NickelValue};
8use crate::{
9 identifier::Ident,
10 term::{BindingType, record::FieldDeps},
11};
12
13pub mod lazy;
14// pub mod incremental;
15
16/// An index to a specific item stored in the cache
17pub type CacheIndex = lazy::Thunk;
18// pub type CacheIndex = usize;
19
20/// The current Cache implementation
21pub type CacheImpl = lazy::CBNCache;
22// pub type CacheImpl = incremental::IncCache;
23
24/// A black-holed node was accessed, which would lead to infinite recursion.
25#[derive(Clone, Copy, Debug, Eq, PartialEq)]
26pub struct BlackholedError;
27
28pub trait Cache: Clone {
29 /// Temporary: as of now we only need this for [lazy::CBNCache].
30 type UpdateIndex;
31
32 /// Gets the [Closure] from the element at index `idx`.
33 fn get(&self, idx: CacheIndex) -> Closure;
34
35 /// Checks whether the element at index `idx` is blackholed and returns a
36 /// [BlackholedError] if it is. Otherwise, returns `Some(idx)` if the element
37 /// needs to be updated, returns `None` if not.
38 /// Should use [Cache::make_update_index].
39 fn get_update_index(
40 &mut self,
41 idx: &mut CacheIndex,
42 ) -> Result<Option<Self::UpdateIndex>, BlackholedError>;
43
44 /// Adds an element into the [Cache] and returns its index.
45 fn add(&mut self, clos: Closure, bty: BindingType) -> CacheIndex;
46
47 /// Applies `f` to the [Closure] stored inside the element at index `idx`.
48 fn patch<F: Fn(&mut Closure)>(&mut self, idx: CacheIndex, f: F);
49
50 /// Clones the [Closure] from the element at index `idx` and applies `f` to it.
51 fn get_then<T, F: FnOnce(&Closure) -> T>(&self, idx: CacheIndex, f: F) -> T;
52
53 /// Updates the [Closure] from the element at index `idx` with `clos`.
54 fn update(&mut self, clos: Closure, idx: Self::UpdateIndex);
55
56 /// Initializes a new [Cache].
57 fn new() -> Self;
58
59 /// Resets the state of the element at index `idx` to `Suspended`
60 fn reset_index_state(&mut self, idx: &mut Self::UpdateIndex);
61
62 fn map_at_index<F: FnMut(&mut Self, &Closure) -> Closure>(
63 &mut self,
64 idx: &CacheIndex,
65 f: F,
66 ) -> CacheIndex;
67
68 /// Initializes the cached value of the element at index `idx` with the given `rec_env`.
69 fn build_cached(&mut self, idx: &mut CacheIndex, rec_env: &[(Ident, CacheIndex)]);
70
71 /// Revert the element at index `idx`, abstract over its dependencies to get back a function,
72 /// and apply the function to the given variables. The function part is allocated in a new
73 /// cache entry, stored as a generated variable, with the same environment as the original
74 /// expression.
75 fn saturate<I: DoubleEndedIterator<Item = Ident> + Clone>(
76 &mut self,
77 idx: CacheIndex,
78 fields: I,
79 ) -> NickelValue;
80
81 /// Reverts the element stored at index `idx` to its original value.
82 fn revert(&mut self, idx: &CacheIndex) -> CacheIndex;
83
84 /// Returns the dependencies of the element stored at index `idx`, if it has any.
85 fn deps(&self, idx: &CacheIndex) -> Option<FieldDeps>;
86
87 /// Checks whether the element at index `idx` is blackholed and returns a
88 /// [BlackholedError] if it is. Otherwise, returns `idx`.
89 fn make_update_index(
90 &mut self,
91 idx: &mut CacheIndex,
92 ) -> Result<Self::UpdateIndex, BlackholedError>;
93}