1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
|
use elsa::vec::FrozenVec;
use once_cell::sync::OnceCell;
use crate::semantics::{Import, ImportLocation};
use crate::syntax::Span;
use crate::Typed;
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub struct ImportId(usize);
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub struct ImportResultId(usize);
struct StoredImport {
base_location: ImportLocation,
import: Import,
span: Span,
result: OnceCell<ImportResultId>,
}
#[derive(Default)]
struct CtxtS {
imports: FrozenVec<Box<StoredImport>>,
import_results: FrozenVec<Box<Typed>>,
}
/// Context for the dhall compiler. Stores various global maps.
#[derive(Copy, Clone)]
pub struct Ctxt<'cx>(&'cx CtxtS);
impl Ctxt<'_> {
pub fn with_new<T>(f: impl for<'cx> FnOnce(Ctxt<'cx>) -> T) -> T {
let cx = CtxtS::default();
let cx = Ctxt(&cx);
f(cx)
}
}
impl<'cx> Ctxt<'cx> {
fn get_stored_import(self, import: ImportId) -> &'cx StoredImport {
self.0.imports.get(import.0).unwrap()
}
pub fn get_import_result(self, id: ImportResultId) -> &'cx Typed {
&self.0.import_results.get(id.0).unwrap()
}
/// Store an import and the location relative to which it must be resolved.
pub fn push_import(
self,
base_location: ImportLocation,
import: Import,
span: Span,
) -> ImportId {
let stored = StoredImport {
base_location,
import,
span,
result: OnceCell::new(),
};
let id = self.0.imports.len();
self.0.imports.push(Box::new(stored));
ImportId(id)
}
/// Store the result of fetching an import.
pub fn push_import_result(self, res: Typed) -> ImportResultId {
let id = self.0.import_results.len();
self.0.import_results.push(Box::new(res));
ImportResultId(id)
}
pub fn get_import(self, import: ImportId) -> &'cx Import {
&self.get_stored_import(import).import
}
pub fn get_import_base_location(
self,
import: ImportId,
) -> &'cx ImportLocation {
&self.get_stored_import(import).base_location
}
pub fn get_import_span(self, import: ImportId) -> Span {
self.get_stored_import(import).span.clone()
}
/// Get the result of fetching this import. Returns `None` if the result has not yet been
/// fetched.
pub fn get_result_of_import(self, import: ImportId) -> Option<&'cx Typed> {
let res = self.get_resultid_of_import(import)?;
Some(self.get_import_result(res))
}
/// Get the id of the result of fetching this import. Returns `None` if the result has not yet
/// been fetched.
pub fn get_resultid_of_import(
self,
import: ImportId,
) -> Option<ImportResultId> {
self.get_stored_import(import).result.get().copied()
}
/// Store the result of fetching this import.
pub fn set_result_of_import(
self,
import: ImportId,
res: Typed,
) -> ImportResultId {
let res = self.push_import_result(res);
self.set_resultid_of_import(import, res);
res
}
/// Store the result of fetching this import.
pub fn set_resultid_of_import(self, import: ImportId, res: ImportResultId) {
let _ = self.get_stored_import(import).result.set(res);
}
}
|