1#![allow(dead_code)]
6#![allow(missing_docs)]
7
8#[allow(dead_code)]
12#[derive(Debug, Clone, PartialEq, Eq)]
13pub struct Span {
14 pub start: usize,
16 pub end: usize,
18 pub line: u32,
20 pub column: u32,
22}
23
24impl Span {
25 #[allow(dead_code)]
27 pub fn new(start: usize, end: usize, line: u32, column: u32) -> Self {
28 Self {
29 start,
30 end,
31 line,
32 column,
33 }
34 }
35
36 #[allow(dead_code)]
38 pub fn dummy() -> Self {
39 Self {
40 start: 0,
41 end: 0,
42 line: 0,
43 column: 0,
44 }
45 }
46
47 #[allow(dead_code)]
49 pub fn len(&self) -> usize {
50 self.end.saturating_sub(self.start)
51 }
52
53 #[allow(dead_code)]
55 pub fn is_empty(&self) -> bool {
56 self.start >= self.end
57 }
58
59 #[allow(dead_code)]
61 pub fn merge(&self, other: &Span) -> Span {
62 Span {
63 start: self.start.min(other.start),
64 end: self.end.max(other.end),
65 line: self.line.min(other.line),
66 column: self.column,
67 }
68 }
69}
70
71#[allow(dead_code)]
73#[derive(Debug, Clone)]
74pub struct Located<T> {
75 pub value: T,
77 pub span: Span,
79}
80
81impl<T> Located<T> {
82 #[allow(dead_code)]
84 pub fn new(value: T, span: Span) -> Self {
85 Self { value, span }
86 }
87
88 #[allow(dead_code)]
90 pub fn dummy(value: T) -> Self {
91 Self {
92 value,
93 span: Span::dummy(),
94 }
95 }
96
97 #[allow(dead_code)]
99 pub fn map<U, F: FnOnce(T) -> U>(self, f: F) -> Located<U> {
100 Located {
101 value: f(self.value),
102 span: self.span,
103 }
104 }
105
106 #[allow(dead_code)]
108 pub fn as_ref(&self) -> Located<&T> {
109 Located {
110 value: &self.value,
111 span: self.span.clone(),
112 }
113 }
114}
115
116#[allow(dead_code)]
122#[derive(Debug, Default)]
123pub struct NameTable {
124 names: Vec<String>,
125}
126
127impl NameTable {
128 #[allow(dead_code)]
130 pub fn new() -> Self {
131 Self::default()
132 }
133
134 #[allow(dead_code)]
137 pub fn intern(&mut self, name: &str) -> usize {
138 if let Some(pos) = self.names.iter().position(|n| n == name) {
139 return pos;
140 }
141 let id = self.names.len();
142 self.names.push(name.to_owned());
143 id
144 }
145
146 #[allow(dead_code)]
148 pub fn lookup(&self, id: usize) -> Option<&str> {
149 self.names.get(id).map(String::as_str)
150 }
151
152 #[allow(dead_code)]
154 pub fn len(&self) -> usize {
155 self.names.len()
156 }
157
158 #[allow(dead_code)]
160 pub fn is_empty(&self) -> bool {
161 self.names.is_empty()
162 }
163
164 #[allow(dead_code)]
166 pub fn clear(&mut self) {
167 self.names.clear();
168 }
169
170 #[allow(dead_code)]
172 pub fn iter(&self) -> impl Iterator<Item = (usize, &str)> {
173 self.names.iter().enumerate().map(|(i, s)| (i, s.as_str()))
174 }
175}
176
177#[allow(dead_code)]
181#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
182pub enum DiagnosticLevel {
183 Note,
185 Warning,
187 Error,
189 Bug,
191}
192
193impl DiagnosticLevel {
194 #[allow(dead_code)]
196 pub fn label(self) -> &'static str {
197 match self {
198 Self::Note => "note",
199 Self::Warning => "warning",
200 Self::Error => "error",
201 Self::Bug => "internal compiler error",
202 }
203 }
204
205 #[allow(dead_code)]
207 pub fn is_fatal(self) -> bool {
208 matches!(self, Self::Error | Self::Bug)
209 }
210}
211
212#[allow(dead_code)]
214#[derive(Debug, Clone)]
215pub struct Diagnostic {
216 pub level: DiagnosticLevel,
218 pub message: String,
220 pub span: Option<Span>,
222 pub help: Option<String>,
224}
225
226impl Diagnostic {
227 #[allow(dead_code)]
229 pub fn error(message: impl Into<String>) -> Self {
230 Self {
231 level: DiagnosticLevel::Error,
232 message: message.into(),
233 span: None,
234 help: None,
235 }
236 }
237
238 #[allow(dead_code)]
240 pub fn warning(message: impl Into<String>) -> Self {
241 Self {
242 level: DiagnosticLevel::Warning,
243 message: message.into(),
244 span: None,
245 help: None,
246 }
247 }
248
249 #[allow(dead_code)]
251 pub fn note(message: impl Into<String>) -> Self {
252 Self {
253 level: DiagnosticLevel::Note,
254 message: message.into(),
255 span: None,
256 help: None,
257 }
258 }
259
260 #[allow(dead_code)]
262 pub fn with_span(mut self, span: Span) -> Self {
263 self.span = Some(span);
264 self
265 }
266
267 #[allow(dead_code)]
269 pub fn with_help(mut self, help: impl Into<String>) -> Self {
270 self.help = Some(help.into());
271 self
272 }
273
274 #[allow(dead_code)]
276 pub fn is_fatal(&self) -> bool {
277 self.level.is_fatal()
278 }
279}
280
281#[allow(dead_code)]
283#[derive(Debug, Default)]
284pub struct DiagnosticBag {
285 items: Vec<Diagnostic>,
286}
287
288impl DiagnosticBag {
289 #[allow(dead_code)]
291 pub fn new() -> Self {
292 Self::default()
293 }
294
295 #[allow(dead_code)]
297 pub fn push(&mut self, diag: Diagnostic) {
298 self.items.push(diag);
299 }
300
301 #[allow(dead_code)]
303 pub fn has_errors(&self) -> bool {
304 self.items.iter().any(|d| d.is_fatal())
305 }
306
307 #[allow(dead_code)]
309 pub fn len(&self) -> usize {
310 self.items.len()
311 }
312
313 #[allow(dead_code)]
315 pub fn is_empty(&self) -> bool {
316 self.items.is_empty()
317 }
318
319 #[allow(dead_code)]
321 pub fn drain(&mut self) -> Vec<Diagnostic> {
322 std::mem::take(&mut self.items)
323 }
324
325 #[allow(dead_code)]
327 pub fn iter(&self) -> impl Iterator<Item = &Diagnostic> {
328 self.items.iter()
329 }
330}
331
332#[allow(dead_code)]
339#[derive(Debug)]
340pub struct ScopeTable<K, V> {
341 scopes: Vec<Vec<(K, V)>>,
342}
343
344impl<K: Eq, V: Clone> ScopeTable<K, V> {
345 #[allow(dead_code)]
347 pub fn new() -> Self {
348 Self {
349 scopes: vec![Vec::new()],
350 }
351 }
352
353 #[allow(dead_code)]
355 pub fn push_scope(&mut self) {
356 self.scopes.push(Vec::new());
357 }
358
359 #[allow(dead_code)]
362 pub fn pop_scope(&mut self) {
363 assert!(self.scopes.len() > 1, "cannot pop root scope");
364 self.scopes.pop();
365 }
366
367 #[allow(dead_code)]
369 pub fn define(&mut self, key: K, value: V) {
370 if let Some(scope) = self.scopes.last_mut() {
371 scope.push((key, value));
372 }
373 }
374
375 #[allow(dead_code)]
377 pub fn lookup(&self, key: &K) -> Option<&V> {
378 for scope in self.scopes.iter().rev() {
379 for (k, v) in scope.iter().rev() {
380 if k == key {
381 return Some(v);
382 }
383 }
384 }
385 None
386 }
387
388 #[allow(dead_code)]
390 pub fn defined_locally(&self, key: &K) -> bool {
391 if let Some(scope) = self.scopes.last() {
392 scope.iter().any(|(k, _)| k == key)
393 } else {
394 false
395 }
396 }
397
398 #[allow(dead_code)]
400 pub fn depth(&self) -> usize {
401 self.scopes.len()
402 }
403}
404
405impl<K: Eq, V: Clone> Default for ScopeTable<K, V> {
406 fn default() -> Self {
407 Self::new()
408 }
409}
410
411#[allow(dead_code)]
415#[derive(Debug, Default)]
416pub struct Counter {
417 next: u64,
418}
419
420impl Counter {
421 #[allow(dead_code)]
423 pub fn new() -> Self {
424 Self::default()
425 }
426
427 #[allow(dead_code)]
429 pub fn starting_at(start: u64) -> Self {
430 Self { next: start }
431 }
432
433 #[allow(dead_code)]
435 pub fn next(&mut self) -> u64 {
436 let val = self.next;
437 self.next += 1;
438 val
439 }
440
441 #[allow(dead_code)]
443 pub fn peek(&self) -> u64 {
444 self.next
445 }
446
447 #[allow(dead_code)]
449 pub fn reset(&mut self) {
450 self.next = 0;
451 }
452}
453
454#[allow(dead_code)]
458#[derive(Debug)]
459pub struct FreshNameGen {
460 prefix: String,
461 counter: Counter,
462}
463
464impl FreshNameGen {
465 #[allow(dead_code)]
467 pub fn new(prefix: impl Into<String>) -> Self {
468 Self {
469 prefix: prefix.into(),
470 counter: Counter::new(),
471 }
472 }
473
474 #[allow(dead_code)]
476 pub fn fresh(&mut self) -> String {
477 let n = self.counter.next();
478 format!("{}_{}", self.prefix, n)
479 }
480
481 #[allow(dead_code)]
483 pub fn fresh_str(&mut self) -> String {
484 self.fresh()
485 }
486
487 #[allow(dead_code)]
489 pub fn reset(&mut self) {
490 self.counter.reset();
491 }
492}
493
494#[allow(dead_code)]
498#[derive(Debug, Default, Clone)]
499pub struct StringSet {
500 items: Vec<String>,
501}
502
503impl StringSet {
504 #[allow(dead_code)]
506 pub fn new() -> Self {
507 Self::default()
508 }
509
510 #[allow(dead_code)]
512 pub fn insert(&mut self, item: impl Into<String>) -> bool {
513 let s = item.into();
514 match self.items.binary_search(&s) {
515 Ok(_) => false,
516 Err(pos) => {
517 self.items.insert(pos, s);
518 true
519 }
520 }
521 }
522
523 #[allow(dead_code)]
525 pub fn contains(&self, item: &str) -> bool {
526 self.items
527 .binary_search_by_key(&item, String::as_str)
528 .is_ok()
529 }
530
531 #[allow(dead_code)]
533 pub fn remove(&mut self, item: &str) -> bool {
534 match self.items.binary_search_by_key(&item, String::as_str) {
535 Ok(pos) => {
536 self.items.remove(pos);
537 true
538 }
539 Err(_) => false,
540 }
541 }
542
543 #[allow(dead_code)]
545 pub fn len(&self) -> usize {
546 self.items.len()
547 }
548
549 #[allow(dead_code)]
551 pub fn is_empty(&self) -> bool {
552 self.items.is_empty()
553 }
554
555 #[allow(dead_code)]
557 pub fn iter(&self) -> impl Iterator<Item = &str> {
558 self.items.iter().map(String::as_str)
559 }
560
561 #[allow(dead_code)]
563 pub fn union(&self, other: &StringSet) -> StringSet {
564 let mut result = self.clone();
565 for item in other.iter() {
566 result.insert(item);
567 }
568 result
569 }
570
571 #[allow(dead_code)]
573 pub fn intersection(&self, other: &StringSet) -> StringSet {
574 let mut result = StringSet::new();
575 for item in self.iter() {
576 if other.contains(item) {
577 result.insert(item);
578 }
579 }
580 result
581 }
582
583 #[allow(dead_code)]
585 pub fn difference(&self, other: &StringSet) -> StringSet {
586 let mut result = StringSet::new();
587 for item in self.iter() {
588 if !other.contains(item) {
589 result.insert(item);
590 }
591 }
592 result
593 }
594}
595
596#[allow(dead_code)]
600#[derive(Debug)]
601pub struct MultiMap<K, V> {
602 inner: Vec<(K, Vec<V>)>,
603}
604
605impl<K, V> Default for MultiMap<K, V> {
606 fn default() -> Self {
607 Self { inner: Vec::new() }
608 }
609}
610
611impl<K: Eq, V> MultiMap<K, V> {
612 #[allow(dead_code)]
614 pub fn new() -> Self {
615 Self::default()
616 }
617
618 #[allow(dead_code)]
620 pub fn insert(&mut self, key: K, value: V) {
621 for (k, vs) in &mut self.inner {
622 if k == &key {
623 vs.push(value);
624 return;
625 }
626 }
627 self.inner.push((key, vec![value]));
628 }
629
630 #[allow(dead_code)]
632 pub fn get(&self, key: &K) -> &[V] {
633 for (k, vs) in &self.inner {
634 if k == key {
635 return vs;
636 }
637 }
638 &[]
639 }
640
641 #[allow(dead_code)]
643 pub fn contains_key(&self, key: &K) -> bool {
644 self.inner.iter().any(|(k, _)| k == key)
645 }
646
647 #[allow(dead_code)]
649 pub fn key_count(&self) -> usize {
650 self.inner.len()
651 }
652
653 #[allow(dead_code)]
655 pub fn remove(&mut self, key: &K) -> Vec<V> {
656 let mut result = Vec::new();
657 let mut i = 0;
658 while i < self.inner.len() {
659 if &self.inner[i].0 == key {
660 let (_, vs) = self.inner.remove(i);
661 result = vs;
662 } else {
663 i += 1;
664 }
665 }
666 result
667 }
668
669 #[allow(dead_code)]
671 pub fn iter(&self) -> impl Iterator<Item = (&K, &[V])> {
672 self.inner.iter().map(|(k, vs)| (k, vs.as_slice()))
673 }
674}
675
676#[allow(dead_code)]
680#[derive(Debug)]
681pub struct Trie<V> {
682 children: Vec<(u8, Trie<V>)>,
683 value: Option<V>,
684}
685
686impl<V> Trie<V> {
687 #[allow(dead_code)]
689 pub fn new() -> Self {
690 Self {
691 children: Vec::new(),
692 value: None,
693 }
694 }
695
696 #[allow(dead_code)]
698 pub fn insert(&mut self, key: &[u8], value: V) {
699 if let Some((first, rest)) = key.split_first() {
700 let child = self.get_or_create_child(*first);
701 child.insert(rest, value);
702 } else {
703 self.value = Some(value);
704 }
705 }
706
707 #[allow(dead_code)]
709 pub fn get(&self, key: &[u8]) -> Option<&V> {
710 if let Some((first, rest)) = key.split_first() {
711 for (b, child) in &self.children {
712 if *b == *first {
713 return child.get(rest);
714 }
715 }
716 None
717 } else {
718 self.value.as_ref()
719 }
720 }
721
722 #[allow(dead_code)]
724 pub fn contains(&self, key: &[u8]) -> bool {
725 self.get(key).is_some()
726 }
727
728 #[allow(dead_code)]
730 pub fn keys_with_prefix(&self, prefix: &[u8]) -> Vec<Vec<u8>> {
731 match prefix.split_first() {
732 Some((first, rest)) => {
733 for (b, child) in &self.children {
734 if *b == *first {
735 return child
736 .keys_with_prefix(rest)
737 .into_iter()
738 .map(|mut k| {
739 k.insert(0, *first);
740 k
741 })
742 .collect();
743 }
744 }
745 Vec::new()
746 }
747 None => self.collect_all(Vec::new()),
748 }
749 }
750
751 fn get_or_create_child(&mut self, byte: u8) -> &mut Trie<V> {
752 for i in 0..self.children.len() {
753 if self.children[i].0 == byte {
754 return &mut self.children[i].1;
755 }
756 }
757 self.children.push((byte, Trie::new()));
758 let last = self.children.len() - 1;
759 &mut self.children[last].1
760 }
761
762 fn collect_all(&self, prefix: Vec<u8>) -> Vec<Vec<u8>> {
763 let mut result = Vec::new();
764 if self.value.is_some() {
765 result.push(prefix.clone());
766 }
767 for (b, child) in &self.children {
768 let mut p = prefix.clone();
769 p.push(*b);
770 result.extend(child.collect_all(p));
771 }
772 result
773 }
774}
775
776impl<V> Default for Trie<V> {
777 fn default() -> Self {
778 Self::new()
779 }
780}
781
782#[allow(dead_code)]
786#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
787pub struct BitSet64(u64);
788
789impl BitSet64 {
790 #[allow(dead_code)]
792 pub const fn empty() -> Self {
793 Self(0)
794 }
795
796 #[allow(dead_code)]
798 pub const fn full() -> Self {
799 Self(u64::MAX)
800 }
801
802 #[allow(dead_code)]
804 pub fn set(&mut self, pos: u8) {
805 debug_assert!(pos < 64);
806 self.0 |= 1u64 << pos;
807 }
808
809 #[allow(dead_code)]
811 pub fn clear(&mut self, pos: u8) {
812 debug_assert!(pos < 64);
813 self.0 &= !(1u64 << pos);
814 }
815
816 #[allow(dead_code)]
818 pub fn test(&self, pos: u8) -> bool {
819 debug_assert!(pos < 64);
820 (self.0 >> pos) & 1 == 1
821 }
822
823 #[allow(dead_code)]
825 pub fn count(&self) -> u32 {
826 self.0.count_ones()
827 }
828
829 #[allow(dead_code)]
831 pub fn is_empty(&self) -> bool {
832 self.0 == 0
833 }
834
835 #[allow(dead_code)]
837 pub fn and(self, other: Self) -> Self {
838 Self(self.0 & other.0)
839 }
840
841 #[allow(dead_code)]
843 pub fn or(self, other: Self) -> Self {
844 Self(self.0 | other.0)
845 }
846
847 #[allow(dead_code)]
849 pub fn xor(self, other: Self) -> Self {
850 Self(self.0 ^ other.0)
851 }
852
853 #[allow(dead_code)]
855 pub fn not(self) -> Self {
856 Self(!self.0)
857 }
858
859 #[allow(dead_code)]
861 pub fn iter_ones(self) -> impl Iterator<Item = u8> {
862 (0u8..64).filter(move |&i| self.test(i))
863 }
864}
865
866#[allow(dead_code)]
870#[derive(Debug, Default)]
871pub struct MinHeap<P: Ord, V> {
872 heap: Vec<(P, V)>,
873}
874
875impl<P: Ord, V> MinHeap<P, V> {
876 #[allow(dead_code)]
878 pub fn new() -> Self {
879 Self { heap: Vec::new() }
880 }
881
882 #[allow(dead_code)]
884 pub fn push(&mut self, priority: P, value: V) {
885 self.heap.push((priority, value));
886 let mut i = self.heap.len() - 1;
887 while i > 0 {
888 let parent = (i - 1) / 2;
889 if self.heap[parent].0 > self.heap[i].0 {
890 self.heap.swap(parent, i);
891 i = parent;
892 } else {
893 break;
894 }
895 }
896 }
897
898 #[allow(dead_code)]
900 pub fn pop(&mut self) -> Option<(P, V)> {
901 if self.heap.is_empty() {
902 return None;
903 }
904 let n = self.heap.len();
905 self.heap.swap(0, n - 1);
906 let min = self.heap.pop();
907 self.sift_down(0);
908 min
909 }
910
911 #[allow(dead_code)]
913 pub fn peek(&self) -> Option<(&P, &V)> {
914 self.heap.first().map(|(p, v)| (p, v))
915 }
916
917 #[allow(dead_code)]
919 pub fn len(&self) -> usize {
920 self.heap.len()
921 }
922
923 #[allow(dead_code)]
925 pub fn is_empty(&self) -> bool {
926 self.heap.is_empty()
927 }
928
929 fn sift_down(&mut self, mut i: usize) {
930 let n = self.heap.len();
931 loop {
932 let left = 2 * i + 1;
933 let right = 2 * i + 2;
934 let mut smallest = i;
935 if left < n && self.heap[left].0 < self.heap[smallest].0 {
936 smallest = left;
937 }
938 if right < n && self.heap[right].0 < self.heap[smallest].0 {
939 smallest = right;
940 }
941 if smallest == i {
942 break;
943 }
944 self.heap.swap(i, smallest);
945 i = smallest;
946 }
947 }
948}
949
950#[allow(dead_code)]
954#[derive(Debug, Clone)]
955pub struct DirectedGraph {
956 adj: Vec<Vec<usize>>,
957}
958
959impl DirectedGraph {
960 #[allow(dead_code)]
962 pub fn new(n: usize) -> Self {
963 Self {
964 adj: vec![Vec::new(); n],
965 }
966 }
967
968 #[allow(dead_code)]
970 pub fn add_edge(&mut self, u: usize, v: usize) {
971 self.adj[u].push(v);
972 }
973
974 #[allow(dead_code)]
976 pub fn node_count(&self) -> usize {
977 self.adj.len()
978 }
979
980 #[allow(dead_code)]
982 pub fn out_degree(&self, u: usize) -> usize {
983 self.adj[u].len()
984 }
985
986 #[allow(dead_code)]
988 pub fn successors(&self, u: usize) -> &[usize] {
989 &self.adj[u]
990 }
991
992 #[allow(dead_code)]
995 pub fn topological_sort(&self) -> Option<Vec<usize>> {
996 let n = self.adj.len();
997 let mut in_deg = vec![0usize; n];
998 for u in 0..n {
999 for &v in &self.adj[u] {
1000 in_deg[v] += 1;
1001 }
1002 }
1003 let mut queue: std::collections::VecDeque<usize> =
1004 (0..n).filter(|&u| in_deg[u] == 0).collect();
1005 let mut order = Vec::new();
1006 while let Some(u) = queue.pop_front() {
1007 order.push(u);
1008 for &v in &self.adj[u] {
1009 in_deg[v] -= 1;
1010 if in_deg[v] == 0 {
1011 queue.push_back(v);
1012 }
1013 }
1014 }
1015 if order.len() == n {
1016 Some(order)
1017 } else {
1018 None
1019 }
1020 }
1021
1022 #[allow(dead_code)]
1024 pub fn strongly_connected_components(&self) -> Vec<Vec<usize>> {
1025 let n = self.adj.len();
1026 let mut visited = vec![false; n];
1028 let mut finish_order = Vec::new();
1029 for start in 0..n {
1030 if !visited[start] {
1031 self.dfs_finish(start, &mut visited, &mut finish_order);
1032 }
1033 }
1034 let mut rev = vec![Vec::new(); n];
1036 for u in 0..n {
1037 for &v in &self.adj[u] {
1038 rev[v].push(u);
1039 }
1040 }
1041 let mut comp = vec![usize::MAX; n];
1043 let mut scc_id = 0;
1044 for &start in finish_order.iter().rev() {
1045 if comp[start] == usize::MAX {
1046 let mut stack = vec![start];
1047 while let Some(u) = stack.pop() {
1048 if comp[u] != usize::MAX {
1049 continue;
1050 }
1051 comp[u] = scc_id;
1052 for &v in &rev[u] {
1053 if comp[v] == usize::MAX {
1054 stack.push(v);
1055 }
1056 }
1057 }
1058 scc_id += 1;
1059 }
1060 }
1061 let mut sccs: Vec<Vec<usize>> = vec![Vec::new(); scc_id];
1062 for u in 0..n {
1063 sccs[comp[u]].push(u);
1064 }
1065 sccs
1066 }
1067
1068 fn dfs_finish(&self, u: usize, visited: &mut Vec<bool>, order: &mut Vec<usize>) {
1069 let mut stack = vec![(u, 0usize)];
1070 while let Some((node, idx)) = stack.last_mut() {
1071 let _node = *node;
1072 if !visited[_node] {
1073 visited[_node] = true;
1074 }
1075 if *idx < self.adj[_node].len() {
1076 let next = self.adj[_node][*idx];
1077 *idx += 1;
1078 if !visited[next] {
1079 stack.push((next, 0));
1080 }
1081 } else {
1082 order.push(_node);
1083 stack.pop();
1084 }
1085 }
1086 }
1087}
1088
1089#[cfg(test)]
1092mod tests {
1093 use super::*;
1094
1095 #[test]
1096 fn test_span_merge() {
1097 let a = Span::new(0, 5, 1, 1);
1098 let b = Span::new(3, 10, 1, 4);
1099 let m = a.merge(&b);
1100 assert_eq!(m.start, 0);
1101 assert_eq!(m.end, 10);
1102 }
1103
1104 #[test]
1105 fn test_located_map() {
1106 let l = Located::dummy(42u32);
1107 let l2 = l.map(|x| x * 2);
1108 assert_eq!(l2.value, 84);
1109 }
1110
1111 #[test]
1112 fn test_name_table() {
1113 let mut t = NameTable::new();
1114 let id_a = t.intern("alpha");
1115 let id_b = t.intern("beta");
1116 let id_a2 = t.intern("alpha");
1117 assert_eq!(id_a, id_a2);
1118 assert_ne!(id_a, id_b);
1119 assert_eq!(t.lookup(id_a), Some("alpha"));
1120 assert_eq!(t.len(), 2);
1121 }
1122
1123 #[test]
1124 fn test_diagnostic_bag() {
1125 let mut bag = DiagnosticBag::new();
1126 assert!(!bag.has_errors());
1127 bag.push(Diagnostic::warning("minor issue"));
1128 assert!(!bag.has_errors());
1129 bag.push(Diagnostic::error("fatal problem"));
1130 assert!(bag.has_errors());
1131 assert_eq!(bag.len(), 2);
1132 let drained = bag.drain();
1133 assert_eq!(drained.len(), 2);
1134 assert!(bag.is_empty());
1135 }
1136
1137 #[test]
1138 fn test_scope_table() {
1139 let mut s: ScopeTable<&str, u32> = ScopeTable::new();
1140 s.define("x", 1);
1141 s.push_scope();
1142 s.define("x", 2);
1143 assert_eq!(s.lookup(&"x"), Some(&2));
1144 s.pop_scope();
1145 assert_eq!(s.lookup(&"x"), Some(&1));
1146 }
1147
1148 #[test]
1149 fn test_counter_and_fresh_name() {
1150 let mut c = Counter::new();
1151 assert_eq!(c.next(), 0);
1152 assert_eq!(c.next(), 1);
1153 assert_eq!(c.peek(), 2);
1154 c.reset();
1155 assert_eq!(c.next(), 0);
1156
1157 let mut gen = FreshNameGen::new("var");
1158 let n0 = gen.fresh();
1159 let n1 = gen.fresh();
1160 assert_eq!(n0, "var_0");
1161 assert_eq!(n1, "var_1");
1162 }
1163
1164 #[test]
1165 fn test_string_set_operations() {
1166 let mut s = StringSet::new();
1167 assert!(s.insert("banana"));
1168 assert!(s.insert("apple"));
1169 assert!(!s.insert("apple")); assert!(s.contains("apple"));
1171 assert!(!s.contains("cherry"));
1172 assert_eq!(s.len(), 2);
1173 assert!(s.remove("apple"));
1174 assert!(!s.contains("apple"));
1175 let mut t = StringSet::new();
1176 t.insert("cherry");
1177 t.insert("banana");
1178 let u = s.union(&t);
1179 assert!(u.contains("banana"));
1180 assert!(u.contains("cherry"));
1181 }
1182
1183 #[test]
1184 fn test_multi_map() {
1185 let mut m: MultiMap<&str, u32> = MultiMap::new();
1186 m.insert("key", 1);
1187 m.insert("key", 2);
1188 m.insert("other", 3);
1189 assert_eq!(m.get(&"key"), &[1, 2]);
1190 assert_eq!(m.key_count(), 2);
1191 let removed = m.remove(&"key");
1192 assert_eq!(removed, vec![1, 2]);
1193 assert!(!m.contains_key(&"key"));
1194 }
1195
1196 #[test]
1197 fn test_trie() {
1198 let mut t: Trie<u32> = Trie::new();
1199 t.insert(b"hello", 1);
1200 t.insert(b"help", 2);
1201 t.insert(b"world", 3);
1202 assert_eq!(t.get(b"hello"), Some(&1));
1203 assert_eq!(t.get(b"help"), Some(&2));
1204 assert!(t.get(b"helo").is_none());
1205 assert!(t.contains(b"world"));
1206 let pfx = t.keys_with_prefix(b"hel");
1207 assert_eq!(pfx.len(), 2);
1208 }
1209
1210 #[test]
1211 fn test_bitset64() {
1212 let mut bs = BitSet64::empty();
1213 assert!(bs.is_empty());
1214 bs.set(5);
1215 bs.set(10);
1216 assert!(bs.test(5));
1217 assert!(bs.test(10));
1218 assert!(!bs.test(0));
1219 assert_eq!(bs.count(), 2);
1220 bs.clear(5);
1221 assert!(!bs.test(5));
1222 let ones: Vec<u8> = bs.iter_ones().collect();
1223 assert_eq!(ones, vec![10]);
1224 }
1225
1226 #[test]
1227 fn test_min_heap() {
1228 let mut heap: MinHeap<u32, &str> = MinHeap::new();
1229 heap.push(5, "five");
1230 heap.push(1, "one");
1231 heap.push(3, "three");
1232 assert_eq!(heap.len(), 3);
1233 let (p, v) = heap.pop().expect("pop should succeed");
1234 assert_eq!(p, 1);
1235 assert_eq!(v, "one");
1236 let (p2, _) = heap.pop().expect("pop should succeed");
1237 assert_eq!(p2, 3);
1238 }
1239
1240 #[test]
1241 fn test_directed_graph_topo_sort() {
1242 let mut g = DirectedGraph::new(4);
1243 g.add_edge(0, 1);
1244 g.add_edge(0, 2);
1245 g.add_edge(1, 3);
1246 g.add_edge(2, 3);
1247 let order = g.topological_sort().expect("should be a DAG");
1248 assert_eq!(order.len(), 4);
1249 let pos: Vec<usize> = {
1251 let mut p = vec![0usize; 4];
1252 for (i, &node) in order.iter().enumerate() {
1253 p[node] = i;
1254 }
1255 p
1256 };
1257 assert!(pos[0] < pos[1]);
1258 assert!(pos[0] < pos[2]);
1259 assert!(pos[1] < pos[3]);
1260 assert!(pos[2] < pos[3]);
1261 }
1262
1263 #[test]
1264 fn test_directed_graph_scc() {
1265 let mut g = DirectedGraph::new(4);
1267 g.add_edge(0, 1);
1268 g.add_edge(1, 2);
1269 g.add_edge(2, 0);
1270 let sccs = g.strongly_connected_components();
1272 assert_eq!(sccs.len(), 2);
1274 }
1275
1276 #[test]
1277 fn test_diagnostic_level_ordering() {
1278 assert!(DiagnosticLevel::Note < DiagnosticLevel::Warning);
1279 assert!(DiagnosticLevel::Warning < DiagnosticLevel::Error);
1280 assert!(DiagnosticLevel::Error < DiagnosticLevel::Bug);
1281 assert!(DiagnosticLevel::Error.is_fatal());
1282 assert!(!DiagnosticLevel::Warning.is_fatal());
1283 }
1284}