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 display;
24
25impl Handle {
26 pub const fn to_entry<'t, 'a>(self, table: &'t Table<'a>) -> Entry<'t, 'a> {
27 Entry { id: self, table }
28 }
29 pub fn to_entry_mut<'t, 'a>(self, table: &'t mut Table<'a>) -> EntryMut<'t, 'a> {
30 EntryMut { id: self, table }
31 }
32}
33
34#[derive(Debug)]
35pub struct Entry<'t, 'a> {
36 table: &'t Table<'a>,
37 id: Handle,
38}
39
40impl<'t, 'a> Entry<'t, 'a> {
41 pub const fn new(table: &'t Table<'a>, id: Handle) -> Self {
42 Self { table, id }
43 }
44
45 pub const fn id(&self) -> Handle {
46 self.id
47 }
48
49 pub fn inner(&self) -> &'t Table<'a> {
50 self.table
51 }
52
53 pub const fn with_id(&self, id: Handle) -> Entry<'t, 'a> {
54 Self { table: self.table, id }
55 }
56
57 pub fn nav(&self, path: &[PathPart]) -> Option<Entry<'t, 'a>> {
58 Some(Entry { id: self.table.nav(self.id, path)?, table: self.table })
59 }
60
61 pub const fn root(&self) -> Handle {
62 self.table.root()
63 }
64
65 pub fn kind(&self) -> Option<&'t NodeKind> {
66 self.table.kind(self.id)
67 }
68
69 pub fn parent(&self) -> Option<Entry<'t, 'a>> {
70 Some(Entry { id: *self.table.parent(self.id)?, ..*self })
71 }
72
73 pub fn children(&self) -> Option<&'t HashMap<Sym, Handle>> {
74 self.table.children(self.id)
75 }
76
77 pub fn imports(&self) -> Option<&'t HashMap<Sym, Handle>> {
78 self.table.imports(self.id)
79 }
80
81 pub fn bodies(&self) -> Option<&'a Expr> {
82 self.table.body(self.id)
83 }
84
85 pub fn ty(&self) -> Option<&'t TypeKind> {
86 self.table.ty(self.id)
87 }
88
89 pub fn span(&self) -> Option<&'t Span> {
90 self.table.span(self.id)
91 }
92
93 pub fn meta(&self) -> Option<&'a [Meta]> {
94 self.table.meta(self.id)
95 }
96
97 pub fn source(&self) -> Option<&'t Source<'a>> {
98 self.table.source(self.id)
99 }
100
101 pub fn impl_target(&self) -> Option<Entry<'_, 'a>> {
102 Some(Entry { id: self.table.impl_target(self.id)?, ..*self })
103 }
104
105 pub fn selfty(&self) -> Option<Entry<'_, 'a>> {
106 Some(Entry { id: self.table.selfty(self.id)?, ..*self })
107 }
108
109 pub fn name(&self) -> Option<Sym> {
110 self.table.name(self.id)
111 }
112}
113
114#[derive(Debug)]
115pub struct EntryMut<'t, 'a> {
116 table: &'t mut Table<'a>,
117 id: Handle,
118}
119
120impl<'t, 'a> EntryMut<'t, 'a> {
121 pub fn new(table: &'t mut Table<'a>, id: Handle) -> Self {
122 Self { table, id }
123 }
124
125 pub fn as_ref(&self) -> Entry<'_, 'a> {
126 Entry { table: self.table, id: self.id }
127 }
128
129 pub const fn id(&self) -> Handle {
130 self.id
131 }
132
133 pub fn evaluate<Out>(&mut self, ty: &impl TypeExpression<Out>) -> Result<Out, tex::Error> {
135 let Self { table, id } = self;
136 ty.evaluate(table, *id)
137 }
138
139 pub fn categorize(&mut self) -> Result<(), cat::Error> {
140 cat::categorize(self.table, self.id)
141 }
142
143 pub fn with_id(&mut self, parent: Handle) -> EntryMut<'_, 'a> {
145 EntryMut { table: self.table, id: parent }
146 }
147
148 pub fn nav(&mut self, path: &[PathPart]) -> Option<EntryMut<'_, 'a>> {
149 Some(EntryMut { id: self.table.nav(self.id, path)?, table: self.table })
150 }
151
152 pub fn new_entry(&mut self, kind: NodeKind) -> EntryMut<'_, 'a> {
153 let id = self.table.new_entry(self.id, kind);
154 self.with_id(id)
155 }
156
157 pub fn add_child(&mut self, name: Sym, child: Handle) -> Option<Handle> {
158 self.table.add_child(self.id, name, child)
159 }
160
161 pub fn set_body(&mut self, body: &'a Expr) -> Option<&'a Expr> {
162 self.table.set_body(self.id, body)
163 }
164
165 pub fn set_ty(&mut self, kind: TypeKind) -> Option<TypeKind> {
166 self.table.set_ty(self.id, kind)
167 }
168
169 pub fn set_span(&mut self, span: Span) -> Option<Span> {
170 self.table.set_span(self.id, span)
171 }
172
173 pub fn set_meta(&mut self, meta: &'a [Meta]) -> Option<&'a [Meta]> {
174 self.table.set_meta(self.id, meta)
175 }
176
177 pub fn set_source(&mut self, source: Source<'a>) -> Option<Source<'a>> {
178 self.table.set_source(self.id, source)
179 }
180
181 pub fn set_impl_target(&mut self, target: Handle) -> Option<Handle> {
182 self.table.set_impl_target(self.id, target)
183 }
184
185 pub fn mark_use_item(&mut self) {
186 self.table.mark_use_item(self.id)
187 }
188
189 pub fn mark_impl_item(&mut self) {
190 self.table.mark_impl_item(self.id)
191 }
192}