1use crate::{
25 entry::{Entry, EntryMut},
26 handle::Handle,
27 type_kind::TypeKind,
28};
29use cl_ast::{
30 Expr,
31 types::{Path, Symbol as Sym},
32};
33use cl_structures::{index_map::IndexMap, intern::interned::Interned};
34use std::collections::{BTreeMap, HashMap};
35
36pub type Map<K, V> = BTreeMap<K, V>;
37pub type SymMap<V> = BTreeMap<Sym, V>;
38
39#[derive(Debug)]
44pub struct Table {
45 root: Handle,
46 kinds: IndexMap<Handle, NodeKind>,
48 parents: IndexMap<Handle, Handle>,
49 pub(crate) children: Map<Handle, SymMap<Handle>>,
50 pub(crate) lazy_imports: Map<Handle, SymMap<Path>>,
51 pub(crate) glob_imports: Map<Handle, Vec<Path>>,
52 pub(crate) names: Map<Handle, Sym>,
53 pub(crate) types: Map<Handle, TypeKind>,
54 pub(crate) metas: Map<Handle, Vec<Expr>>,
55 pub(crate) impls: Map<Handle, Vec<Handle>>,
56 pub(crate) impl_targets: Map<Handle, Handle>,
57 pub(crate) anon_types: HashMap<TypeKind, Handle>,
58 pub(crate) lang_items: Map<&'static str, Handle>,
59
60 pub(crate) unchecked_handles: Vec<Handle>,
62 pub(crate) pending_impls: Vec<Handle>,
63}
64
65impl Table {
66 pub fn new() -> Self {
67 let mut kinds = IndexMap::new();
68 let mut parents = IndexMap::new();
69 let root = kinds.insert(NodeKind::Root);
70 assert_eq!(root, parents.insert(root));
71
72 Self {
73 root,
74 kinds,
75 parents,
76 children: Map::new(),
77 lazy_imports: Map::new(),
78 glob_imports: Map::new(),
79 names: Map::new(),
80 types: Map::new(),
81 metas: Map::new(),
82 impls: Map::new(),
83 impl_targets: Map::new(),
84 anon_types: HashMap::new(),
85 lang_items: Map::new(),
86 unchecked_handles: Vec::new(),
87 pending_impls: Vec::new(),
88 }
89 }
90
91 pub fn entry(&self, handle: Handle) -> Entry<'_> {
93 handle.to_entry(self)
94 }
95
96 pub fn entry_mut(&mut self, handle: Handle) -> EntryMut<'_> {
98 handle.to_entry_mut(self)
99 }
100
101 pub fn new_entry(&mut self, parent: Handle, kind: NodeKind) -> Handle {
103 let entry = self.kinds.insert(kind);
104 assert_eq!(entry, self.parents.insert(parent));
105 entry
106 }
107
108 pub fn add_child(&mut self, parent: Handle, name: Sym, child: Handle) -> Option<Handle> {
110 self.children.entry(parent).or_default().insert(name, child)
111 }
112
113 pub fn mark_unchecked(&mut self, item: Handle) {
115 self.unchecked_handles.push(item);
116 }
117
118 pub fn mark_impl_item(&mut self, item: Handle) {
120 let parent = self.parent(item).copied().unwrap_or(item);
121 self.impls.entry(parent).or_default().push(item);
122 self.pending_impls.push(item);
123 }
124
125 pub fn mark_lang_item(&mut self, name: &'static str, item: Handle) {
127 self.lang_items.insert(name, item);
128 }
129
130 pub fn get_lang_item(&self, name: &str) -> Handle {
132 match self.lang_items.get(name).copied() {
133 Some(handle) => handle,
134 None => todo!(),
135 }
136 }
137
138 pub fn handle_iter(&self) -> impl Iterator<Item = Handle> + use<> {
140 self.kinds.keys()
141 }
142
143 pub fn debug_entry_iter(&self) -> impl Iterator<Item = Entry<'_>> {
145 self.kinds.keys().map(|key| key.to_entry(self))
146 }
147
148 pub(crate) fn anon_type(&mut self, kind: TypeKind) -> Handle {
151 if let Some(id) = self.anon_types.get(&kind) {
152 return *id;
153 }
154 let entry = self.new_entry(self.root, NodeKind::Type);
155 self.types.insert(entry, kind.clone());
157 self.anon_types.insert(kind, entry);
158 entry
159 }
160
161 pub(crate) fn inferred_type(&mut self) -> Handle {
163 let handle = self.new_entry(self.root, NodeKind::Type);
164 self.types.insert(handle, TypeKind::Inferred);
165 handle
166 }
167
168 pub(crate) fn type_variable(&mut self) -> Handle {
170 let handle = self.new_entry(self.root, NodeKind::Type);
171 self.types.insert(handle, TypeKind::Variable);
172 handle
173 }
174
175 pub const fn root_entry(&self) -> Entry<'_> {
177 self.root.to_entry(self)
178 }
179
180 pub fn root_entry_mut(&mut self) -> crate::entry::EntryMut<'_> {
182 self.root.to_entry_mut(self)
183 }
184
185 pub const fn root(&self) -> Handle {
189 self.root
190 }
191
192 pub fn kind(&self, node: Handle) -> Option<&NodeKind> {
194 self.kinds.get(node)
195 }
196
197 pub fn parent(&self, node: Handle) -> Option<&Handle> {
199 self.parents.get(node)
200 }
201
202 pub fn children(&self, node: Handle) -> Option<&SymMap<Handle>> {
204 self.children.get(&node)
205 }
206
207 pub fn lazy_imports(&self, node: Handle) -> Option<&SymMap<Path>> {
209 self.lazy_imports.get(&node)
210 }
211
212 pub fn glob_imports(&self, node: Handle) -> Option<&[Path]> {
214 self.glob_imports.get(&node).map(Vec::as_slice)
215 }
216
217 pub fn ty(&self, node: Handle) -> Option<&TypeKind> {
219 self.types.get(&node)
220 }
221
222 pub fn meta(&self, node: Handle) -> Option<&[Expr]> {
224 self.metas.get(&node).map(Vec::as_slice)
225 }
226
227 pub fn impl_target(&self, node: Handle) -> Option<Handle> {
229 self.impl_targets.get(&node).copied()
230 }
231
232 pub fn reparent(&mut self, node: Handle, parent: Handle) -> Handle {
234 self.parents.replace(node, parent)
235 }
236
237 pub fn add_import(&mut self, node: Handle, name: Sym, path: Path) {
239 self.lazy_imports
240 .entry(node)
241 .or_default()
242 .insert(name, path);
243 }
244
245 pub fn add_glob(&mut self, node: Handle, path: Path) {
247 self.glob_imports.entry(node).or_default().push(path);
248 }
249
250 pub fn set_name(&mut self, node: Handle, name: Sym) -> Option<Sym> {
252 self.names.insert(node, name)
253 }
254
255 pub fn set_ty(&mut self, node: Handle, kind: TypeKind) -> Option<TypeKind> {
257 self.types.insert(node, kind)
258 }
259
260 pub fn set_meta(&mut self, node: Handle, meta: Vec<Expr>) {
262 self.metas.entry(node).or_default().extend(meta);
263 }
264
265 pub fn add_meta(&mut self, node: Handle, meta: Expr) {
266 self.metas.entry(node).or_default().push(meta);
267 }
268
269 pub fn set_impl_target(&mut self, node: Handle, target: Handle) -> Option<Handle> {
271 self.impl_targets.insert(node, target)
272 }
273
274 pub fn selfty(&self, node: Handle) -> Option<Handle> {
278 match self.kinds.get(node)? {
279 NodeKind::Root | NodeKind::Use => None,
280 NodeKind::Type => Some(node),
281 NodeKind::Impl => self.impl_target(node),
282 _ => self.selfty(*self.parent(node)?),
283 }
284 }
285
286 pub fn super_of(&self, node: Handle) -> Option<Handle> {
288 match self.kinds.get(node)? {
289 NodeKind::Root => None,
290 NodeKind::Module => self.parent(node).copied(),
291 _ => self.super_of(*self.parent(node)?),
292 }
293 }
294
295 pub fn name(&self, node: Handle) -> Option<Sym> {
297 self.names.get(&node).copied()
298 }
299
300 pub fn is_transparent(&self, node: Handle) -> bool {
302 !matches!(
303 self.kind(node),
304 None | Some(NodeKind::Root | NodeKind::Module)
305 )
306 }
307
308 pub fn get_child(&self, node: Handle, name: &Sym) -> Option<Handle> {
310 self.children.get(&node).and_then(|c| c.get(name)).copied()
311 }
312
313 pub fn get_import(&self, node: Handle, name: &Sym) -> Option<Handle> {
315 if let Some(path) = self.lazy_imports(node).and_then(|t| t.get(name)) {
316 return self.nav(node, &path.parts);
317 }
318 self.glob_imports(node)
319 .into_iter()
320 .flatten()
321 .rev()
322 .flat_map(|path| self.nav(node, &path.parts))
323 .find_map(|node| self.get_by_sym(node, name))
324 }
325
326 pub fn get_by_sym(&self, node: Handle, name: &Sym) -> Option<Handle> {
327 self.get_child(node, name)
328 .or_else(|| {
329 self.is_transparent(node)
330 .then(|| {
331 self.parent(node)
332 .and_then(|node| self.get_by_sym(*node, name))
333 })
334 .flatten()
335 })
336 .or_else(|| self.get_import(node, name))
337 }
338
339 pub fn nav(&self, node: Handle, path: &[Sym]) -> Option<Handle> {
341 match path {
347 [Interned("", ..), rest @ ..] => self.nav(self.root, rest),
348 [Interned("super", ..), rest @ ..] => self.nav(self.super_of(node)?, rest),
349 [Interned("Self", ..), rest @ ..] => self.nav(self.selfty(node)?, rest),
350 [name, rest @ ..] => self.nav(self.get_by_sym(node, name)?, rest),
351 [] => Some(node),
352 }
353 }
354}
355
356impl Default for Table {
357 fn default() -> Self {
358 Self::new()
359 }
360}
361
362#[derive(Clone, Copy, Debug)]
363pub enum NodeKind {
364 Root,
365 Module,
366 Type,
367 Const,
368 Static,
369 Function,
370 Temporary,
371 Let,
372 Scope,
373 Impl,
374 Use,
375}
376
377mod display {
378 use super::*;
379 use std::fmt;
380 impl fmt::Display for NodeKind {
381 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
382 match self {
383 NodeKind::Root => write!(f, "root"),
384 NodeKind::Module => write!(f, "mod"),
385 NodeKind::Type => write!(f, "type"),
386 NodeKind::Const => write!(f, "const"),
387 NodeKind::Static => write!(f, "static"),
388 NodeKind::Function => write!(f, "fn"),
389 NodeKind::Temporary => write!(f, "temp"),
390 NodeKind::Let => write!(f, "let"),
391 NodeKind::Scope => write!(f, "scope"),
392 NodeKind::Use => write!(f, "use"),
393 NodeKind::Impl => write!(f, "impl"),
394 }
395 }
396 }
397}