1use std::collections::HashMap;
10
11use cl_ast::{Expr, Meta, PathPart, Sym};
12use cl_structures::span::Span;
13
14use crate::{
15 handle::Handle,
16 source::Source,
17 stage::categorize as cat,
18 table::{NodeKind, Table},
19 type_expression::{self as tex, TypeExpression},
20 type_kind::TypeKind,
21};
22
23mod debug;
24mod display;
25
26impl Handle {
27 pub const fn to_entry<'t, 'a>(self, table: &'t Table<'a>) -> Entry<'t, 'a> {
28 Entry { id: self, table }
29 }
30 pub fn to_entry_mut<'t, 'a>(self, table: &'t mut Table<'a>) -> EntryMut<'t, 'a> {
31 EntryMut { id: self, table }
32 }
33}
34
35pub struct Entry<'t, 'a> {
36 table: &'t Table<'a>,
37 id: Handle,
38}
39
40macro_rules! impl_entry_ {
41 () => {
42 pub const fn id(&self) -> Handle {
43 self.id
44 }
45
46 pub const fn inner(&'t self) -> &'t Table<'a> {
47 self.table
48 }
49
50 pub fn kind(&self) -> Option<&NodeKind> {
51 self.table.kind(self.id)
52 }
53
54 pub const fn root(&self) -> Handle {
55 self.table.root()
56 }
57
58 pub fn children(&self) -> Option<&HashMap<Sym, Handle>> {
59 self.table.children(self.id)
60 }
61
62 pub fn imports(&self) -> Option<&HashMap<Sym, Handle>> {
63 self.table.imports(self.id)
64 }
65
66 pub fn bodies(&self) -> Option<&'a Expr> {
67 self.table.body(self.id)
68 }
69
70 pub fn span(&self) -> Option<&Span> {
71 self.table.span(self.id)
72 }
73
74 pub fn meta(&self) -> Option<&[Meta]> {
75 self.table.meta(self.id)
76 }
77
78 pub fn source(&self) -> Option<&Source<'a>> {
79 self.table.source(self.id)
80 }
81
82 pub fn name(&self) -> Option<Sym> {
83 self.table.name(self.id)
84 }
85 };
86}
87
88impl<'t, 'a> Entry<'t, 'a> {
89 pub const fn new(table: &'t Table<'a>, id: Handle) -> Self {
90 Self { table, id }
91 }
92
93 impl_entry_!();
94
95 pub const fn with_id(&self, id: Handle) -> Entry<'t, 'a> {
96 Self { table: self.table, id }
97 }
98
99 pub fn nav(&self, path: &[PathPart]) -> Option<Entry<'t, 'a>> {
100 Some(Entry { id: self.table.nav(self.id, path)?, table: self.table })
101 }
102
103 pub fn parent(&self) -> Option<Entry<'t, 'a>> {
104 Some(Entry { id: *self.table.parent(self.id)?, ..*self })
105 }
106
107 pub fn ty(&self) -> Option<&'t TypeKind> {
108 self.table.ty(self.id)
109 }
110
111 pub fn impl_target(&self) -> Option<Entry<'_, 'a>> {
112 Some(Entry { id: self.table.impl_target(self.id)?, ..*self })
113 }
114
115 pub fn selfty(&self) -> Option<Entry<'_, 'a>> {
116 Some(Entry { id: self.table.selfty(self.id)?, ..*self })
117 }
118}
119
120#[derive(Debug)]
121pub struct EntryMut<'t, 'a> {
122 table: &'t mut Table<'a>,
123 id: Handle,
124}
125
126impl<'t, 'a> EntryMut<'t, 'a> {
127 pub fn new(table: &'t mut Table<'a>, id: Handle) -> Self {
128 Self { table, id }
129 }
130
131 impl_entry_!();
132
133 pub fn ty(&self) -> Option<&TypeKind> {
134 self.table.ty(self.id)
135 }
136
137 pub fn inner_mut(&mut self) -> &mut Table<'a> {
138 self.table
139 }
140
141 pub fn as_ref(&self) -> Entry<'_, 'a> {
142 Entry { table: self.table, id: self.id }
143 }
144
145 pub fn evaluate<Out>(&mut self, ty: &impl TypeExpression<Out>) -> Result<Out, tex::Error> {
147 let Self { table, id } = self;
148 ty.evaluate(table, *id)
149 }
150
151 pub fn categorize(&mut self) -> Result<(), cat::Error> {
152 cat::categorize(self.table, self.id)
153 }
154
155 pub fn with_id(&mut self, parent: Handle) -> EntryMut<'_, 'a> {
157 EntryMut { table: self.table, id: parent }
158 }
159
160 pub fn nav(&mut self, path: &[PathPart]) -> Option<EntryMut<'_, 'a>> {
161 Some(EntryMut { id: self.table.nav(self.id, path)?, table: self.table })
162 }
163
164 pub fn new_entry(&mut self, kind: NodeKind) -> EntryMut<'_, 'a> {
165 let id = self.table.new_entry(self.id, kind);
166 self.with_id(id)
167 }
168
169 pub fn add_child(&mut self, name: Sym, child: Handle) -> Option<Handle> {
170 self.table.add_child(self.id, name, child)
171 }
172
173 pub fn set_body(&mut self, body: &'a Expr) -> Option<&'a Expr> {
174 self.table.set_body(self.id, body)
175 }
176
177 pub fn set_ty(&mut self, kind: TypeKind) -> Option<TypeKind> {
178 self.table.set_ty(self.id, kind)
179 }
180
181 pub fn set_span(&mut self, span: Span) -> Option<Span> {
182 self.table.set_span(self.id, span)
183 }
184
185 pub fn set_meta(&mut self, meta: &'a [Meta]) -> Option<&'a [Meta]> {
186 self.table.set_meta(self.id, meta)
187 }
188
189 pub fn set_source(&mut self, source: Source<'a>) -> Option<Source<'a>> {
190 self.table.set_source(self.id, source)
191 }
192
193 pub fn set_impl_target(&mut self, target: Handle) -> Option<Handle> {
194 self.table.set_impl_target(self.id, target)
195 }
196
197 pub fn mark_unchecked(&mut self) {
198 self.table.mark_unchecked(self.id)
199 }
200
201 pub fn mark_use_item(&mut self) {
202 self.table.mark_use_item(self.id)
203 }
204
205 pub fn mark_impl_item(&mut self) {
206 self.table.mark_impl_item(self.id)
207 }
208
209 pub fn mark_lang_item(&mut self, lang_item: &'static str) {
210 self.table.mark_lang_item(lang_item, self.id)
211 }
212}