1use crate::analysis::lookahead_dfa::ProductionIndex;
4use crate::generators::symbol_table_facade::InstanceItem;
5use crate::grammar::{ProductionAttribute, SymbolAttribute};
6use crate::parser::parol_grammar::UserDefinedTypeName;
7use crate::{generators::NamingHelper as NmHlp, utils::generate_name};
8use anyhow::{Result, bail};
9use parol_runtime::log::trace;
10use petgraph::algo::tarjan_scc;
11use petgraph::visit::NodeRef;
12use petgraph::{
13 algo::is_cyclic_directed,
14 dot::{Config, Dot},
15 graph::NodeIndex,
16 prelude::DiGraph,
17};
18use serde::{Deserialize, Serialize};
19use ts_rs::TS;
20
21use std::collections::HashMap;
22use std::fmt::{Debug, Display, Error, Formatter};
23use std::ops::{Index, IndexMut};
24
25use super::symbol_table_facade::{InstanceFacade, SymbolFacade, SymbolItem, TypeFacade, TypeItem};
26
27#[derive(
29 Clone, Copy, Debug, Default, PartialEq, Serialize, Deserialize, Eq, Hash, Ord, PartialOrd, TS,
30)]
31#[ts(export)]
32pub(crate) struct SymbolId(usize);
33
34impl Display for SymbolId {
35 fn fmt(&self, f: &mut Formatter<'_>) -> std::result::Result<(), Error> {
36 write!(f, "Sym({})", self.0)
37 }
38}
39
40#[derive(Clone, Copy, Debug, Default, PartialEq, Serialize, Deserialize, TS)]
42#[ts(export)]
43pub(crate) struct ScopedNameId(ScopeId, usize);
44
45impl ScopedNameId {
46 pub(crate) fn is_unnamed(&self) -> bool {
47 self.1 == Scope::UNNAMED_TYPE_NAME_ID
48 }
49}
50
51impl Display for ScopedNameId {
52 fn fmt(&self, f: &mut Formatter<'_>) -> std::result::Result<(), Error> {
53 write!(f, "Nam({}, {})", self.0, self.1)
54 }
55}
56
57#[derive(Clone, Copy, Debug, Default, PartialEq, Serialize, Deserialize, TS)]
59#[ts(export)]
60pub(crate) struct ScopeId(usize);
61
62impl Display for ScopeId {
63 fn fmt(&self, f: &mut Formatter<'_>) -> std::result::Result<(), Error> {
64 write!(f, "Sco({})", self.0)
65 }
66}
67
68#[derive(Builder, Clone, Debug, Default, PartialEq, Serialize, Deserialize, TS)]
72#[ts(export)]
73pub(crate) struct Function {
74 pub(crate) non_terminal: String,
76
77 #[builder(default)]
79 pub(crate) sem: ProductionAttribute,
80
81 #[builder(default)]
83 pub(crate) prod_num: ProductionIndex,
84
85 #[builder(default)]
87 pub(crate) rel_idx: usize,
88
89 #[builder(default)]
92 pub(crate) alts: usize,
93
94 #[builder(default)]
96 pub(crate) prod_string: String,
97}
98
99impl Function {
100 pub(crate) fn to_rust(&self, fn_name: String) -> String {
101 format!(
102 "fn {} /* NT: {}{} Prod: {}, Rel: {}, Alts: {} */",
103 fn_name,
104 self.non_terminal,
105 match self.sem {
106 ProductionAttribute::None => "".to_string(),
107 _ => format!(", {}", self.sem),
108 },
109 self.prod_num,
110 self.rel_idx,
111 self.alts,
112 )
113 }
114}
115
116#[derive(Clone, Copy, Debug, PartialEq, Serialize, Deserialize, TS)]
117#[ts(export)]
118pub(crate) enum MetaSymbolKind {
119 Module,
121 Token,
123 NonTerminal(SymbolId),
125}
126
127impl Display for MetaSymbolKind {
128 fn fmt(&self, f: &mut Formatter<'_>) -> std::result::Result<(), Error> {
129 match self {
130 MetaSymbolKind::Module => write!(f, "Module"),
131 MetaSymbolKind::Token => write!(f, "Tok"),
132 MetaSymbolKind::NonTerminal(t) => write!(f, "Nt({t})"),
133 }
134 }
135}
136
137#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, TS)]
141#[ts(export)]
142#[derive(Default)]
143pub(crate) enum TypeEntrails {
144 #[default]
146 None,
147 Token,
149 Box(SymbolId),
151 Ref(SymbolId),
153 Surrogate(SymbolId),
155 Struct,
157 Enum,
159 EnumVariant(SymbolId),
161 Vec(SymbolId),
163 Trait,
165 Function(Function),
167 Option(SymbolId),
169 Clipped(MetaSymbolKind),
171 UserDefinedType(MetaSymbolKind, UserDefinedTypeName),
173}
174
175impl TypeEntrails {
176 pub(crate) fn inner_name(&self, symbol_table: &SymbolTable) -> String {
177 match self {
178 TypeEntrails::Box(t)
179 | TypeEntrails::Surrogate(t)
180 | TypeEntrails::Ref(t)
181 | TypeEntrails::Vec(t)
182 | TypeEntrails::Option(t)
183 | TypeEntrails::UserDefinedType(MetaSymbolKind::NonTerminal(t), _) => {
184 symbol_table.symbol(*t).name()
185 }
186 _ => "No inner name available!".to_string(),
187 }
188 }
189
190 pub(crate) fn sem(&self) -> SymbolAttribute {
191 SymbolAttribute::None
192 }
193
194 pub(crate) fn is_container(&self) -> bool {
195 matches!(self, Self::Vec(_) | Self::Option(_) | Self::Box(_))
196 }
197}
198
199#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize, TS)]
203#[ts(export)]
204pub(crate) struct Type {
205 pub(crate) entrails: TypeEntrails,
207
208 pub(crate) member_scope: ScopeId,
210}
211
212impl Type {
213 pub(crate) fn to_rust(&self, symbol_table: &SymbolTable, my_symbol: &Symbol) -> String {
214 let uses_type_name = || {
216 matches!(self.entrails, TypeEntrails::Struct)
217 | matches!(self.entrails, TypeEntrails::Enum)
218 | matches!(self.entrails, TypeEntrails::EnumVariant(_))
219 | matches!(self.entrails, TypeEntrails::Function(_))
220 | matches!(self.entrails, TypeEntrails::Trait)
221 };
222 let my_type_name = if uses_type_name() {
223 let my_type = symbol_table.symbol_as_type(my_symbol.my_id);
224 my_type.inner_name()
225 } else {
226 symbol_table.name(my_symbol.my_id).to_owned()
227 };
228 let lifetime = symbol_table.lifetime(my_symbol.my_id);
229 match &self.entrails {
230 TypeEntrails::None => "*TypeError*".to_string(),
231 TypeEntrails::Token => format!("Token{lifetime}"),
232 TypeEntrails::Box(r) => {
233 format!("Box<{}>", symbol_table.symbol(*r).to_rust())
234 }
235 TypeEntrails::Ref(r) => {
236 let inner_type = symbol_table.symbol(*r);
237 format!("&{}", inner_type.to_rust())
238 }
239 TypeEntrails::Struct => format!("{my_type_name}{lifetime}"),
240 TypeEntrails::Enum => format!("{my_type_name}{lifetime}"),
241 TypeEntrails::EnumVariant(t) => {
242 format!(
243 "{}({}),",
244 my_type_name,
245 symbol_table.symbol_as_type(*t).to_rust(),
246 )
247 }
248 TypeEntrails::Vec(r) => format!(
249 "Vec<{}{}>",
250 symbol_table.symbol(*r).name(),
251 symbol_table.lifetime(*r)
252 ),
253 TypeEntrails::Trait => format!("trait {my_type_name}{lifetime}"),
254 TypeEntrails::Function(f) => f.to_rust(my_type_name),
255 TypeEntrails::Option(o) => format!("Option<{}>", symbol_table.symbol(*o).to_rust()),
256 TypeEntrails::Clipped(k) => format!("Clipped({k})"),
257 TypeEntrails::UserDefinedType(_, u) => u.get_module_scoped_name(),
258 TypeEntrails::Surrogate(s) => format!(
259 "{}{}",
260 symbol_table.symbol(*s).name(),
261 symbol_table.lifetime(*s)
262 ),
263 }
264 }
265
266 pub(crate) fn inner_name(&self, symbol_table: &SymbolTable, my_symbol: &Symbol) -> String {
268 let is_user_defined_type = matches!(self.entrails, TypeEntrails::UserDefinedType(..));
269 if is_user_defined_type || my_symbol.name_id.is_unnamed() {
270 self.entrails.inner_name(symbol_table)
271 } else {
272 symbol_table.name(my_symbol.my_id).to_string()
273 }
274 }
275
276 pub(crate) fn inner_type(&self) -> Option<SymbolId> {
278 match self.entrails {
279 TypeEntrails::Box(t)
280 | TypeEntrails::Surrogate(t)
281 | TypeEntrails::Ref(t)
282 | TypeEntrails::EnumVariant(t)
283 | TypeEntrails::Vec(t)
284 | TypeEntrails::Option(t) => Some(t),
285 _ => None,
286 }
287 }
288
289 pub(crate) fn sem(&self) -> SymbolAttribute {
290 self.entrails.sem()
291 }
292}
293
294#[derive(Builder, Clone, Debug, Default, PartialEq, Serialize, Deserialize, TS)]
298#[ts(export)]
299pub(crate) struct InstanceEntrails {
300 #[builder(default)]
302 pub(crate) used: bool,
303}
304
305#[derive(Builder, Clone, Debug, Default, PartialEq, Serialize, Deserialize, TS)]
309#[ts(export)]
310pub(crate) struct Instance {
311 pub(crate) scope: ScopeId,
313
314 pub(crate) type_id: SymbolId,
316
317 pub(crate) entrails: InstanceEntrails,
319
320 pub(crate) sem: SymbolAttribute,
322
323 pub(crate) description: String,
325}
326
327impl Instance {
328 fn to_rust(&self, symbol_table: &SymbolTable, my_symbol: &Symbol) -> String {
329 let desc = if self.description.is_empty() {
330 String::default()
331 } else {
332 format!(
334 "/* {} */",
335 self.description.replace("*/", "*\\/").replace("/*", "/\\*")
336 )
337 };
338 format!(
339 "{}: {}, {}",
340 self.name(symbol_table, my_symbol),
341 symbol_table.symbol(self.type_id).to_rust(),
342 desc,
343 )
344 }
345
346 pub(crate) fn name(&self, symbol_table: &SymbolTable, my_symbol: &Symbol) -> String {
347 symbol_table.name(my_symbol.my_id).to_string()
348 }
349
350 fn inner_type(&self) -> Option<SymbolId> {
351 Some(self.type_id)
352 }
353
354 pub(crate) fn sem(&self) -> SymbolAttribute {
355 self.sem
356 }
357}
358
359#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, TS)]
363#[ts(export)]
364pub(crate) enum SymbolKind {
365 Type(Type),
366 Instance(Instance),
367}
368
369#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, TS)]
373#[ts(export)]
374pub struct Symbol {
375 pub(crate) my_id: SymbolId,
377
378 pub(crate) name_id: ScopedNameId,
380
381 pub(crate) kind: SymbolKind,
383
384 pub(crate) has_lifetime: bool,
386}
387
388impl Symbol {
389 pub(crate) fn new(
390 my_id: SymbolId,
391 name_id: ScopedNameId,
392 kind: SymbolKind,
393 lifetime: bool,
394 ) -> Self {
395 Self {
396 my_id,
397 name_id,
398 kind,
399 has_lifetime: lifetime,
400 }
401 }
402
403 pub(crate) fn my_id(&self) -> SymbolId {
404 self.my_id
405 }
406
407 fn inner_type(&self) -> Option<SymbolId> {
408 match &self.kind {
409 SymbolKind::Type(t) => t.inner_type(),
410 SymbolKind::Instance(i) => i.inner_type(),
411 }
412 }
413
414 fn set_inner_type(&mut self, inner_type: SymbolId) -> Result<()> {
416 match &mut self.kind {
417 SymbolKind::Type(t) => match t.entrails {
418 TypeEntrails::Box(ref mut i)
419 | TypeEntrails::Ref(ref mut i)
420 | TypeEntrails::Surrogate(ref mut i)
421 | TypeEntrails::EnumVariant(ref mut i)
422 | TypeEntrails::Vec(ref mut i)
423 | TypeEntrails::Option(ref mut i)
424 | TypeEntrails::Clipped(MetaSymbolKind::NonTerminal(ref mut i)) => {
425 *i = inner_type;
426 }
427 _ => bail!("Have no inner type!"),
428 },
429 SymbolKind::Instance(_) => bail!("Ain't no type!"),
430 }
431 Ok(())
432 }
433
434 pub(crate) fn to_rust(&self, symbol_table: &SymbolTable) -> String {
435 match &self.kind {
436 SymbolKind::Type(t) => t.to_rust(symbol_table, self),
437 SymbolKind::Instance(i) => i.to_rust(symbol_table, self),
438 }
439 }
440
441 pub(crate) fn member_scope(&self) -> Option<ScopeId> {
442 match &self.kind {
443 SymbolKind::Type(t) => Some(t.member_scope),
444 SymbolKind::Instance(_) => None,
445 }
446 }
447
448 pub(crate) fn sem(&self) -> SymbolAttribute {
449 match &self.kind {
450 SymbolKind::Type(t) => t.sem(),
451 SymbolKind::Instance(i) => i.sem(),
452 }
453 }
454}
455#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, TS)]
459#[ts(export)]
460pub(crate) struct Scope {
461 pub(crate) parent: Option<ScopeId>,
462 pub(crate) my_id: ScopeId,
463 pub(crate) symbols: Vec<SymbolId>,
464 names: Vec<String>,
465}
466
467impl Scope {
468 const UNNAMED_TYPE_NAME_ID: usize = 0;
469
470 pub(crate) fn new(parent: Option<ScopeId>, my_id: ScopeId) -> Self {
471 Self {
472 parent,
473 my_id,
474 symbols: Vec::new(),
475 names: vec![SymbolTable::UNNAMED_TYPE.to_string()],
476 }
477 }
478
479 pub(crate) fn make_unique_name(&self, preferred_name: String) -> String {
480 if preferred_name == SymbolTable::UNNAMED_TYPE {
481 SymbolTable::UNNAMED_TYPE.to_string()
482 } else {
483 generate_name(self.names.iter(), preferred_name)
484 }
485 }
486
487 pub(crate) fn add_name(&mut self, name: String) -> ScopedNameId {
488 if name == SymbolTable::UNNAMED_TYPE {
489 ScopedNameId(self.my_id, Self::UNNAMED_TYPE_NAME_ID)
490 } else {
491 let name_id = ScopedNameId(self.my_id, self.names.len());
492 self.names.push(name);
493 name_id
494 }
495 }
496
497 fn insert_type(
498 &mut self,
499 name: &str,
500 symbol_id: SymbolId,
501 member_scope: ScopeId,
502 entrails: TypeEntrails,
503 ) -> Symbol {
504 let type_name = match entrails {
505 TypeEntrails::Function(_) => self.make_unique_name(NmHlp::to_lower_snake_case(name)),
506 TypeEntrails::UserDefinedType(..) => name.to_owned(),
507 _ => self.make_unique_name(NmHlp::to_upper_camel_case(name)),
508 };
509 trace!(
510 "Scope {}: Inserting type {}({}) {:?}",
511 self.my_id, type_name, symbol_id, entrails
512 );
513 let name_id = self.add_name(type_name);
514 self.symbols.push(symbol_id);
515 Symbol::new(
516 symbol_id,
517 name_id,
518 SymbolKind::Type(Type {
519 entrails,
520 member_scope,
521 }),
522 false,
523 )
524 }
525
526 fn insert_instance(
527 &mut self,
528 name: &str,
529 symbol_id: SymbolId,
530 type_id: SymbolId,
531 entrails: InstanceEntrails,
532 sem: SymbolAttribute,
533 description: &str,
534 ) -> Symbol {
535 let instance_name = self.make_unique_name(NmHlp::to_lower_snake_case(name));
536 let name_id = self.add_name(instance_name);
537 self.symbols.push(symbol_id);
538 trace!(
539 "Scope {}: Inserting instance {}({}) (type: {}) {:?}",
540 self.my_id, name, symbol_id, type_id, entrails
541 );
542 Symbol::new(
543 symbol_id,
544 name_id,
545 SymbolKind::Instance(Instance {
546 scope: self.my_id,
547 type_id,
548 entrails,
549 sem,
550 description: description.to_owned(),
551 }),
552 false,
553 )
554 }
555
556 fn has_symbol(&self, symbol_id: SymbolId) -> bool {
557 self.symbols.contains(&symbol_id)
558 }
559
560 pub(crate) fn symbol_by_name(
561 &self,
562 symbol_table: &SymbolTable,
563 name: &str,
564 ) -> Option<SymbolId> {
565 self.symbols
566 .iter()
567 .find(|s| {
568 let symbol = symbol_table.symbol(**s);
569 debug_assert_eq!(symbol.name_id().0, self.my_id);
570 self.names[symbol.name_id().1] == name
571 })
572 .copied()
573 }
574
575 pub(crate) fn to_rust(&self, symbol_table: &SymbolTable) -> String {
576 let mut result = String::new();
577 result.push_str(&format!("// Scope: {}\n", self.my_id));
578 for symbol_id in &self.symbols {
579 result.push_str(&format!("{}\n", symbol_table.symbol(*symbol_id).to_rust()));
580 }
581 result
582 }
583}
584
585impl Display for Scope {
586 fn fmt(&self, f: &mut Formatter<'_>) -> std::result::Result<(), Error> {
587 write!(
588 f,
589 "// Scope: my_id: {}, parent: {}\n// Symbols:\n{}\n// Names:\n{}",
590 self.my_id,
591 self.parent
592 .map_or("No parent".to_string(), |i| format!("{i}")),
593 self.symbols
594 .iter()
595 .map(|s| s.to_string())
596 .collect::<Vec<String>>()
597 .join("\n"),
598 self.names
599 .iter()
600 .enumerate()
601 .map(|(i, n)| format!("{}: {}", ScopedNameId(self.my_id, i), n))
602 .collect::<Vec<String>>()
603 .join("\n"),
604 )
605 }
606}
607
608#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize, TS)]
618#[ts(export)]
619pub struct SymbolTable {
620 pub(crate) symbols: Vec<Symbol>,
622
623 pub(crate) scopes: Vec<Scope>,
626}
627
628impl SymbolTable {
629 pub(crate) const GLOBAL_SCOPE: ScopeId = ScopeId(0);
630 pub(crate) const UNNAMED_TYPE: &'static str = "";
634
635 pub(crate) fn new() -> Self {
637 Self {
638 symbols: Vec::new(),
639 scopes: vec![Scope::new(None, Self::GLOBAL_SCOPE)],
640 }
641 }
642
643 pub(crate) fn next_symbol_id(&self) -> SymbolId {
646 SymbolId(self.symbols.len())
647 }
648
649 pub(crate) fn next_scope_id(&self) -> ScopeId {
652 ScopeId(self.scopes.len())
653 }
654
655 pub(crate) fn has_lifetime(&self, symbol_id: SymbolId) -> bool {
657 self[symbol_id].has_lifetime
658 }
659
660 pub(crate) fn lifetime(&self, symbol_id: SymbolId) -> String {
662 if self[symbol_id].has_lifetime {
663 "<'t>".to_string()
664 } else {
665 "".to_string()
666 }
667 }
668
669 pub(crate) fn elided_lifetime(&self, symbol_id: SymbolId) -> String {
671 if self[symbol_id].has_lifetime {
672 "<'_>".to_string()
673 } else {
674 "".to_string()
675 }
676 }
677
678 pub(crate) fn name(&self, symbol_id: SymbolId) -> &str {
680 let name_id = &self[symbol_id].name_id;
681 &self.scope(name_id.0).names[name_id.1]
682 }
683
684 pub(crate) fn members(&self, type_id: SymbolId) -> Result<&[SymbolId]> {
686 let type_symbol = self.symbol_as_type(type_id);
687 Ok(&self.scope(type_symbol.member_scope()).symbols)
688 }
689
690 pub(crate) fn scope(&self, scope_id: ScopeId) -> &Scope {
692 &self[scope_id]
693 }
694
695 pub(crate) fn scope_mut(&mut self, scope_id: ScopeId) -> &mut Scope {
697 &mut self[scope_id]
698 }
699
700 pub(crate) fn symbol(&self, symbol_id: SymbolId) -> impl SymbolFacade<'_> {
702 SymbolItem::new(&self[symbol_id], self)
703 }
704
705 pub(crate) fn type_name(&self, symbol_id: SymbolId) -> Result<String> {
707 let type_symbol = self.symbol(symbol_id);
708 debug_assert!(matches!(type_symbol.kind(), SymbolKind::Type(_)));
709 Ok(type_symbol.name())
710 }
711
712 pub(crate) fn _instance_name(&self, symbol_id: SymbolId) -> Result<String> {
714 let instance_symbol = self.symbol(symbol_id);
715 debug_assert!(matches!(instance_symbol.kind(), SymbolKind::Instance(_)));
716 Ok(instance_symbol.name())
717 }
718
719 pub(crate) fn symbol_as_instance(&self, symbol_id: SymbolId) -> impl InstanceFacade<'_> {
721 let instance_symbol = self.symbol(symbol_id);
722 debug_assert!(
723 matches!(instance_symbol.kind(), SymbolKind::Instance(_)),
724 "Symbol {} is not an instance: {:?}!",
725 symbol_id,
726 instance_symbol.kind()
727 );
728 let instance = match &self[symbol_id].kind {
729 SymbolKind::Type(_) => panic!("Ain't no instance!"),
730 SymbolKind::Instance(i) => i,
731 };
732 InstanceItem::new(SymbolItem::new(&self[symbol_id], self), instance)
733 }
734
735 pub(crate) fn set_instance_used(&mut self, symbol_id: SymbolId, used: bool) -> Result<()> {
737 match &mut self[symbol_id].kind {
738 SymbolKind::Type(_) => bail!("Ain't no instance!"),
739 SymbolKind::Instance(i) => i.entrails.used &= used,
740 }
741 Ok(())
742 }
743
744 pub(crate) fn symbol_as_type(&self, symbol_id: SymbolId) -> impl TypeFacade<'_> {
746 let symbol_type = match &self[symbol_id].kind {
747 SymbolKind::Type(t) => t,
748 SymbolKind::Instance(_) => panic!("Ain't no type!"),
749 };
750 TypeItem::new(SymbolItem::new(&self[symbol_id], self), symbol_type)
751 }
752
753 pub(crate) fn symbol_as_function(&self, symbol_id: SymbolId) -> Result<Function> {
755 let function_type = self.symbol_as_type(symbol_id);
756 match function_type.entrails() {
757 TypeEntrails::Function(f) => Ok(f.clone()),
758 _ => bail!("Expecting a function here"),
759 }
760 }
761
762 pub(crate) fn function_type_semantic(
764 &self,
765 symbol_id: SymbolId,
766 ) -> Result<ProductionAttribute> {
767 let function_type = self.symbol_as_type(symbol_id);
768 match function_type.entrails() {
769 TypeEntrails::Function(f) => Ok(f.sem),
770 _ => bail!("Expecting a function here"),
771 }
772 }
773
774 fn insert_scope(&mut self, parent: Option<ScopeId>) -> ScopeId {
776 let my_id = self.next_scope_id();
777 self.scopes.push(Scope::new(parent, my_id));
778 my_id
779 }
780
781 fn insert_symbol(&mut self, mut symbol: Symbol) -> SymbolId {
783 let symbol_id = self.next_symbol_id();
784 let is_clipped = symbol.sem() == SymbolAttribute::Clipped;
785 symbol.has_lifetime = !is_clipped
786 && matches!(
787 symbol.kind,
788 SymbolKind::Type(Type {
789 entrails: TypeEntrails::Token,
790 ..
791 })
792 );
793 self.symbols.push(symbol);
794 symbol_id
795 }
796
797 fn find_containing_scopes(&self, symbol_id: SymbolId) -> Vec<ScopeId> {
799 self.scopes
800 .iter()
801 .filter(|scope| scope.has_symbol(symbol_id))
802 .map(|scope| scope.my_id)
803 .collect::<Vec<ScopeId>>()
804 }
805
806 fn find_symbols_with_member_scopes(&self, scope_ids: &[ScopeId]) -> Vec<SymbolId> {
808 self.symbols
809 .iter()
810 .filter(|symbol| {
811 if let Some(scope) = symbol.member_scope() {
812 symbol.sem() != SymbolAttribute::Clipped && scope_ids.contains(&scope)
813 } else {
814 false
815 }
816 })
817 .map(|symbol| symbol.my_id())
818 .collect::<Vec<SymbolId>>()
819 }
820
821 fn symbols_with_lifetime(&self) -> Vec<SymbolId> {
823 self.symbols
824 .iter()
825 .enumerate()
826 .filter_map(|(i, symbol)| {
827 if symbol.has_lifetime {
828 debug_assert_eq!(i, symbol.my_id().0);
829 Some(symbol.my_id())
830 } else {
831 None
832 }
833 })
834 .collect::<Vec<SymbolId>>()
835 }
836
837 fn propagate_lifetime(&mut self, symbol_id: SymbolId) {
839 let parent_scope_ids = self.find_containing_scopes(symbol_id);
840 let parent_symbols = self.find_symbols_with_member_scopes(&parent_scope_ids);
841 for parent_symbol in &parent_symbols {
842 self[*parent_symbol].has_lifetime = true;
843 }
844 let containing_symbols = self
845 .symbols
846 .iter()
847 .filter(|symbol| {
848 if let Some(inner_type) = symbol.inner_type() {
849 inner_type == symbol_id
850 } else {
851 false
852 }
853 })
854 .map(|symbol| symbol.my_id())
855 .collect::<Vec<SymbolId>>();
856
857 for containing_symbol in &containing_symbols {
858 self[*containing_symbol].has_lifetime = true;
859 }
860 }
861
862 pub(crate) fn propagate_lifetimes(&mut self) {
864 let mut symbols_with_lifetime = self.symbols_with_lifetime();
865 let mut count = symbols_with_lifetime.len();
866 let mut old_count = 0;
867 while count != old_count {
868 old_count = count;
869 for symbol_id in symbols_with_lifetime {
870 self.propagate_lifetime(symbol_id);
871 }
872 symbols_with_lifetime = self.symbols_with_lifetime();
873 count = symbols_with_lifetime.len();
874 }
875 }
876
877 pub(crate) fn insert_type(
879 &mut self,
880 parent_symbol: SymbolId,
881 type_name: &str,
882 entrails: TypeEntrails,
883 ) -> Result<SymbolId> {
884 debug_assert!(parent_symbol.0 < self.symbols.len());
885 let parent_scope = self
886 .scope(self.symbol_as_type(parent_symbol).member_scope())
887 .my_id;
888 self.insert_type_in_scope(parent_scope, type_name, entrails)
889 }
890
891 pub(crate) fn insert_type_in_scope(
893 &mut self,
894 parent_scope: ScopeId,
895 type_name: &str,
896 entrails: TypeEntrails,
897 ) -> Result<SymbolId> {
898 let symbol_id = self.next_symbol_id();
899 let member_scope = self.insert_scope(Some(parent_scope));
900 let symbol =
901 self.scope_mut(parent_scope)
902 .insert_type(type_name, symbol_id, member_scope, entrails);
903 Ok(self.insert_symbol(symbol))
904 }
905
906 pub(crate) fn insert_global_type(
909 &mut self,
910 type_name: &str,
911 entrails: TypeEntrails,
912 ) -> Result<SymbolId> {
913 let symbol_id = self.next_symbol_id();
914 let member_scope = self.insert_scope(Some(SymbolTable::GLOBAL_SCOPE));
915 let symbol = self.scope_mut(Self::GLOBAL_SCOPE).insert_type(
916 type_name,
917 symbol_id,
918 member_scope,
919 entrails,
920 );
921 Ok(self.insert_symbol(symbol))
922 }
923
924 pub(crate) fn insert_instance(
927 &mut self,
928 parent_symbol: SymbolId,
929 instance_name: &str,
930 type_id: SymbolId,
931 entrails: InstanceEntrails,
932 sem: SymbolAttribute,
933 description: &str,
934 ) -> Result<SymbolId> {
935 debug_assert!(parent_symbol.0 < self.symbols.len());
936 let symbol_id = self.next_symbol_id();
937 let member_scope = self.symbol_as_type(parent_symbol).member_scope();
938 let symbol = self.scope_mut(member_scope).insert_instance(
939 instance_name,
940 symbol_id,
941 type_id,
942 entrails,
943 sem,
944 description,
945 );
946 Ok(self.insert_symbol(symbol))
947 }
948
949 pub(crate) fn get_or_create_type(
952 &mut self,
953 type_name: &str,
954 scope: ScopeId,
955 entrails: TypeEntrails,
956 ) -> Result<SymbolId> {
957 if let Some(symbol_id) = self.scope(scope).symbols.iter().find(|symbol_id| {
958 let type_symbol = self.symbol_as_type(**symbol_id);
959 *type_symbol.entrails() == entrails && self.name(**symbol_id) == type_name
960 }) {
961 return Ok(*symbol_id);
962 }
963
964 if scope == Self::GLOBAL_SCOPE {
966 self.insert_global_type(type_name, entrails)
967 } else {
968 self.insert_type_in_scope(scope, type_name, entrails)
969 }
970 }
971
972 pub(crate) fn get_global_type(&self, non_terminal: &str) -> Option<SymbolId> {
974 self.scope(Self::GLOBAL_SCOPE)
975 .symbols
976 .iter()
977 .find(|symbol_id| self.name(**symbol_id) == non_terminal)
978 .copied()
979 }
980
981 pub(crate) fn get_or_create_scoped_user_defined_type(
985 &mut self,
986 symbol_kind: MetaSymbolKind,
987 user_defined_type: &UserDefinedTypeName,
988 ) -> Result<SymbolId> {
989 let mut symbol_id: SymbolId = SymbolId::default();
990 let mut parent_scope = Self::GLOBAL_SCOPE;
991 let mut stacked_names = Vec::new();
992 let last = user_defined_type.len() - 1;
993 for (i, type_part) in user_defined_type.names().iter().enumerate() {
994 stacked_names.push(type_part.to_string());
995 let symbol_kind = if i == last {
996 symbol_kind
997 } else {
998 MetaSymbolKind::Module
999 };
1000 symbol_id = self.get_or_create_type(
1001 type_part,
1002 parent_scope,
1003 TypeEntrails::UserDefinedType(
1004 symbol_kind,
1005 UserDefinedTypeName::new(stacked_names.clone()),
1006 ),
1007 )?;
1008 parent_scope = self.symbol_as_type(symbol_id).member_scope();
1009 }
1010 Ok(symbol_id)
1011 }
1012
1013 pub(crate) fn replace_type_of_inst(
1015 &mut self,
1016 inst_symbol_id: SymbolId,
1017 new_type_id: SymbolId,
1018 ) -> Result<()> {
1019 match &mut self[inst_symbol_id].kind {
1020 SymbolKind::Type(_) => panic!("Ain't no instance!"),
1021 SymbolKind::Instance(i) => {
1022 trace!("Replacing type of instance {inst_symbol_id} with type {new_type_id}");
1023 i.type_id = new_type_id
1024 }
1025 };
1026 Ok(())
1027 }
1028
1029 pub(crate) fn replace_wrapped_type(
1030 &mut self,
1031 parent_type: SymbolId,
1032 type_symbol_id: SymbolId,
1033 referred_type_id: SymbolId,
1034 ) -> Result<()> {
1035 debug_assert!(matches!(
1036 self.symbol(type_symbol_id).kind(),
1037 SymbolKind::Type(_)
1038 ));
1039 let parent_scope_id = self.symbol_as_type(parent_type).member_scope();
1040 let parent_scope = self.scope_mut(parent_scope_id);
1041 if parent_scope.symbols.contains(&type_symbol_id) {
1042 self[type_symbol_id].set_inner_type(referred_type_id)?;
1043 } else {
1045 bail!(
1046 "Type {} not found in scope {}",
1047 type_symbol_id,
1048 parent_scope_id
1049 );
1050 }
1051 Ok(())
1052 }
1053
1054 fn recursive_add_symbols(
1055 &self,
1056 graph: &mut DiGraph<SymbolId, ()>,
1057 node_map: &mut HashMap<SymbolId, NodeIndex>,
1058 symbol: SymbolId,
1059 ) {
1060 fn get_or_add_node(
1062 graph: &mut DiGraph<SymbolId, ()>,
1063 node_map: &mut HashMap<SymbolId, NodeIndex>,
1064 symbol: SymbolId,
1065 ) -> NodeIndex {
1066 if let Some(node_id) = node_map.get(&symbol) {
1067 *node_id
1068 } else {
1069 let node_id = graph.add_node(symbol);
1070 node_map.insert(symbol, node_id);
1071 node_id
1072 }
1073 }
1074 let symbol = &self[symbol];
1075 match &symbol.kind {
1076 SymbolKind::Type(_t) => {
1077 let from_node_id = get_or_add_node(graph, node_map, symbol.my_id);
1078 let type_symbol = self.symbol_as_type(symbol.my_id);
1079 match type_symbol.entrails() {
1080 TypeEntrails::Surrogate(t)
1081 | TypeEntrails::EnumVariant(t)
1082 | TypeEntrails::UserDefinedType(MetaSymbolKind::NonTerminal(t), _)
1083 | TypeEntrails::Option(t) => {
1084 let to_node_id = get_or_add_node(graph, node_map, *t);
1086 if graph.find_edge(from_node_id, to_node_id).is_none() {
1087 graph.add_edge(from_node_id, to_node_id, ());
1088 } else {
1089 return;
1090 }
1091 self.recursive_add_symbols(graph, node_map, *t);
1092 }
1093 TypeEntrails::Struct | TypeEntrails::Enum => {
1094 for member in self.members(symbol.my_id).unwrap() {
1098 let to_node_id = get_or_add_node(graph, node_map, *member);
1100 if graph.find_edge(from_node_id, to_node_id).is_none() {
1101 graph.add_edge(from_node_id, to_node_id, ());
1102 } else {
1103 return;
1104 }
1105 self.recursive_add_symbols(graph, node_map, *member);
1106 }
1107 }
1108 _ => {}
1109 }
1110 }
1111 SymbolKind::Instance(i) => {
1112 let from_node_id = get_or_add_node(graph, node_map, symbol.my_id);
1113 let to_node_id = get_or_add_node(graph, node_map, i.type_id);
1114 if graph.find_edge(from_node_id, to_node_id).is_none() {
1115 graph.add_edge(from_node_id, to_node_id, ());
1116 } else {
1117 return;
1118 }
1119 self.recursive_add_symbols(graph, node_map, i.type_id);
1120 }
1121 }
1122 }
1123
1124 pub(crate) fn find_type_cycles(&self) -> Vec<Vec<SymbolId>> {
1126 let mut graph = DiGraph::<SymbolId, ()>::new();
1130 let mut node_map: HashMap<SymbolId, NodeIndex> = HashMap::new();
1131
1132 for symbol in &self[SymbolTable::GLOBAL_SCOPE].symbols {
1133 self.recursive_add_symbols(&mut graph, &mut node_map, *symbol);
1134 }
1135 trace!(
1136 "Type graph: \n{:?}",
1137 Dot::with_attr_getters(
1138 &graph,
1139 &[Config::EdgeNoLabel, Config::NodeNoLabel],
1140 &|_, _| { String::default() },
1141 &|_, n| { format!("label = \"{} {}\"", self.name(*n.weight()), n.weight()) }
1142 )
1143 );
1144 if !is_cyclic_directed(&graph) {
1145 return Vec::new();
1147 }
1148
1149 let sccs: Vec<Vec<NodeIndex>> = tarjan_scc(&graph);
1152
1153 sccs.into_iter()
1155 .filter(|scc| scc.len() > 1)
1156 .map(|scc| {
1157 let mut cycle_ids = scc
1158 .iter()
1159 .map(|&node_idx| *graph.node_weight(node_idx).unwrap())
1160 .collect::<Vec<SymbolId>>();
1161 cycle_ids.sort();
1162 cycle_ids
1163 })
1164 .collect::<Vec<Vec<SymbolId>>>()
1165 }
1166
1167 pub(crate) fn remove_recursivity(&mut self) -> Result<()> {
1168 loop {
1169 let cycles = self.find_type_cycles();
1170 if cycles.is_empty() {
1171 break;
1172 }
1173 self.inner_remove_recursivity(cycles)?;
1174 }
1175 Ok(())
1176 }
1177
1178 fn inner_remove_recursivity(&mut self, cycles: Vec<Vec<SymbolId>>) -> Result<()> {
1179 for cycle in cycles {
1180 if let Some(symbol_id) = cycle.iter().find(|s| match &self[**s].kind {
1184 SymbolKind::Type(t) => match t.entrails {
1185 TypeEntrails::EnumVariant(e) => {
1186 let wrapped_type = self.symbol_as_type(e);
1187 !matches!(wrapped_type.entrails(), TypeEntrails::Box(_))
1189 }
1190 _ => false,
1191 },
1192 SymbolKind::Instance(i) => {
1193 let wrapped_type = self.symbol_as_type(i.type_id);
1195 !matches!(wrapped_type.entrails(), TypeEntrails::Box(_))
1197 }
1198 }) {
1199 let symbol = self[*symbol_id].clone();
1200 match symbol.kind {
1201 SymbolKind::Type(t) => {
1202 if let TypeEntrails::EnumVariant(t) = &t.entrails {
1203 let boxed_type = self.get_or_create_type(
1205 SymbolTable::UNNAMED_TYPE,
1206 SymbolTable::GLOBAL_SCOPE,
1207 TypeEntrails::Box(*t),
1208 )?;
1209 let parent_enum = self
1211 .symbols
1212 .iter()
1213 .find(|s| {
1214 if let SymbolKind::Type(t) = &s.kind {
1215 if matches!(t.entrails, TypeEntrails::Enum) {
1216 self.members(s.my_id()).unwrap().contains(symbol_id)
1217 } else {
1218 false
1219 }
1220 } else {
1221 false
1222 }
1223 })
1224 .unwrap();
1225 self.replace_wrapped_type(parent_enum.my_id, *symbol_id, boxed_type)?;
1226 }
1227 }
1228 SymbolKind::Instance(i) => {
1229 let type_entrails = self.symbol_as_type(i.type_id).entrails().clone();
1230 if let TypeEntrails::Option(t) = type_entrails {
1231 let wrapped_type_entrails = self.symbol_as_type(t).entrails().clone();
1232 if !matches!(wrapped_type_entrails, TypeEntrails::Box(_)) {
1233 let boxed_type = self.get_or_create_type(
1236 SymbolTable::UNNAMED_TYPE,
1237 SymbolTable::GLOBAL_SCOPE,
1238 TypeEntrails::Box(t),
1239 )?;
1240 let option_of_boxed_type = self.get_or_create_type(
1241 SymbolTable::UNNAMED_TYPE,
1242 SymbolTable::GLOBAL_SCOPE,
1243 TypeEntrails::Option(boxed_type),
1244 )?;
1245 self.replace_type_of_inst(*symbol_id, option_of_boxed_type)?;
1246 }
1247 } else {
1257 let boxed_type = self.get_or_create_type(
1259 SymbolTable::UNNAMED_TYPE,
1260 SymbolTable::GLOBAL_SCOPE,
1261 TypeEntrails::Box(i.type_id),
1262 )?;
1263 self.replace_type_of_inst(*symbol_id, boxed_type)?;
1265 }
1266 }
1267 }
1268 }
1269 }
1270 Ok(())
1271 }
1272}
1273
1274impl Index<SymbolId> for SymbolTable {
1275 type Output = Symbol;
1276
1277 fn index(&self, index: SymbolId) -> &Self::Output {
1278 &self.symbols[index.0]
1279 }
1280}
1281
1282impl IndexMut<SymbolId> for SymbolTable {
1283 fn index_mut(&mut self, index: SymbolId) -> &mut Self::Output {
1284 &mut self.symbols[index.0]
1285 }
1286}
1287
1288impl Index<ScopeId> for SymbolTable {
1289 type Output = Scope;
1290
1291 fn index(&self, index: ScopeId) -> &Self::Output {
1292 &self.scopes[index.0]
1293 }
1294}
1295
1296impl IndexMut<ScopeId> for SymbolTable {
1297 fn index_mut(&mut self, index: ScopeId) -> &mut Self::Output {
1298 &mut self.scopes[index.0]
1299 }
1300}
1301
1302impl Index<ScopedNameId> for SymbolTable {
1303 type Output = str;
1304
1305 fn index(&self, index: ScopedNameId) -> &Self::Output {
1306 &self.scope(index.0).names[index.1]
1307 }
1308}
1309
1310impl IndexMut<ScopedNameId> for SymbolTable {
1311 fn index_mut(&mut self, index: ScopedNameId) -> &mut Self::Output {
1312 &mut self.scope_mut(index.0).names[index.1]
1313 }
1314}
1315
1316impl Display for SymbolTable {
1317 fn fmt(&self, f: &mut Formatter<'_>) -> std::result::Result<(), Error> {
1318 writeln!(f, "// Symbols:")?;
1319 for (i, sym) in self.symbols.iter().enumerate() {
1320 writeln!(f, "Sym({}): {}", i, sym.to_rust(self))?;
1321 }
1322 writeln!(f, "// Scopes:")?;
1323 for scope in &self.scopes {
1324 writeln!(f, "{scope}")?;
1325 }
1326 writeln!(f, "// Scope hierarchy:")?;
1327 write!(f, "{}", self.scope(Self::GLOBAL_SCOPE).to_rust(self))
1328 }
1329}
1330
1331#[cfg(test)]
1332mod tests {
1333 use super::*;
1334 #[test]
1335 fn test_scope_relations() {
1336 let mut symbol_table = SymbolTable::new();
1337 assert_eq!(1, symbol_table.scopes.len());
1339 assert_eq!(None, symbol_table.scope(SymbolTable::GLOBAL_SCOPE).parent);
1341
1342 let struct_id = symbol_table
1343 .insert_global_type("StructA", TypeEntrails::Struct)
1344 .expect("insert_global_type should succeed");
1345 assert_eq!(0, struct_id.0);
1346
1347 assert_eq!(2, symbol_table.scopes.len());
1349 assert_eq!(
1351 Some(SymbolTable::GLOBAL_SCOPE),
1352 symbol_table.scope(ScopeId(1)).parent
1353 );
1354
1355 if let SymbolKind::Type(struct_type) = &symbol_table.symbol(struct_id).kind() {
1356 let symbol = symbol_table.symbol(struct_id);
1357 assert_eq!(0, symbol.my_id().0);
1358 assert_eq!(1, symbol.name_id().1);
1359 assert_eq!(
1360 Some(SymbolTable::GLOBAL_SCOPE),
1361 symbol_table.scope(struct_type.member_scope).parent
1362 );
1363 assert_eq!(1, struct_type.member_scope.0);
1364 assert_eq!(1, symbol_table.scope(struct_type.member_scope).names.len());
1366 assert_eq!("StructA", symbol_table.name(symbol.my_id()));
1367 } else {
1368 panic!("StructA should be a type!");
1369 }
1370
1371 let fn_id = symbol_table
1372 .insert_type(
1373 struct_id,
1374 "new",
1375 TypeEntrails::Function(Function::default()),
1376 )
1377 .expect("insert_type should succeed");
1378
1379 if let SymbolKind::Type(struct_type) = &symbol_table.symbol(struct_id).kind() {
1380 assert_eq!(2, symbol_table.scope(struct_type.member_scope).names.len());
1381 } else {
1382 panic!("StructA should be a type!");
1383 }
1384
1385 assert_eq!(3, symbol_table.scopes.len());
1387
1388 if let SymbolKind::Type(fn_type) = &symbol_table.symbol(fn_id).kind() {
1389 let symbol = symbol_table.symbol(fn_id);
1390 assert_eq!(1, symbol.my_id().0);
1391 assert_eq!(1, symbol.name_id().1);
1392 assert_eq!(
1393 Some(ScopeId(1)),
1394 symbol_table.scope(fn_type.member_scope).parent
1395 );
1396 assert_eq!(2, fn_type.member_scope.0);
1397 assert_eq!(1, symbol_table.scope(fn_type.member_scope).names.len());
1398 assert_eq!("new", symbol_table.name(symbol.my_id()));
1399 };
1400 }
1401}