1use super::functions::*;
6use crate::{Expr, Name};
7use std::collections::HashMap;
8
9#[allow(dead_code)]
11pub struct StringPool {
12 free: Vec<String>,
13}
14#[allow(dead_code)]
15impl StringPool {
16 pub fn new() -> Self {
18 Self { free: Vec::new() }
19 }
20 pub fn take(&mut self) -> String {
22 self.free.pop().unwrap_or_default()
23 }
24 pub fn give(&mut self, mut s: String) {
26 s.clear();
27 self.free.push(s);
28 }
29 pub fn free_count(&self) -> usize {
31 self.free.len()
32 }
33}
34#[allow(dead_code)]
36#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Default)]
37pub enum InstancePriority {
38 Low = 0,
40 #[default]
42 Normal = 100,
43 High = 200,
45 Forced = 1000,
47}
48impl InstancePriority {
49 #[allow(dead_code)]
51 pub fn from_u32(n: u32) -> Self {
52 match n {
53 0..=50 => InstancePriority::Low,
54 51..=150 => InstancePriority::Normal,
55 151..=500 => InstancePriority::High,
56 _ => InstancePriority::Forced,
57 }
58 }
59 #[allow(dead_code)]
61 pub fn value(self) -> u32 {
62 self as u32
63 }
64}
65#[allow(dead_code)]
67pub struct VersionedRecord<T: Clone> {
68 earlier: Vec<T>,
70 current: T,
72}
73#[allow(dead_code)]
74impl<T: Clone> VersionedRecord<T> {
75 pub fn new(initial: T) -> Self {
77 Self {
78 earlier: Vec::new(),
79 current: initial,
80 }
81 }
82 pub fn update(&mut self, val: T) {
84 let previous = std::mem::replace(&mut self.current, val);
85 self.earlier.push(previous);
86 }
87 pub fn current(&self) -> &T {
89 &self.current
90 }
91 pub fn at_version(&self, n: usize) -> Option<&T> {
93 match self.earlier.get(n) {
94 Some(value) => Some(value),
95 None if n == self.earlier.len() => Some(&self.current),
96 None => None,
97 }
98 }
99 pub fn version(&self) -> usize {
101 self.earlier.len()
102 }
103 pub fn has_history(&self) -> bool {
105 !self.earlier.is_empty()
106 }
107}
108#[allow(dead_code)]
110#[allow(missing_docs)]
111pub enum DecisionNode {
112 Leaf(String),
114 Branch {
116 key: String,
117 val: String,
118 yes_branch: Box<DecisionNode>,
119 no_branch: Box<DecisionNode>,
120 },
121}
122#[allow(dead_code)]
123impl DecisionNode {
124 pub fn evaluate(&self, ctx: &std::collections::HashMap<String, String>) -> &str {
126 match self {
127 DecisionNode::Leaf(action) => action.as_str(),
128 DecisionNode::Branch {
129 key,
130 val,
131 yes_branch,
132 no_branch,
133 } => {
134 let actual = ctx.get(key).map(|s| s.as_str()).unwrap_or("");
135 if actual == val.as_str() {
136 yes_branch.evaluate(ctx)
137 } else {
138 no_branch.evaluate(ctx)
139 }
140 }
141 }
142 }
143 pub fn depth(&self) -> usize {
145 match self {
146 DecisionNode::Leaf(_) => 0,
147 DecisionNode::Branch {
148 yes_branch,
149 no_branch,
150 ..
151 } => 1 + yes_branch.depth().max(no_branch.depth()),
152 }
153 }
154}
155#[allow(dead_code)]
157#[allow(missing_docs)]
158pub struct RewriteRule {
159 pub name: String,
161 pub lhs: String,
163 pub rhs: String,
165 pub conditional: bool,
167}
168#[allow(dead_code)]
169impl RewriteRule {
170 pub fn unconditional(
172 name: impl Into<String>,
173 lhs: impl Into<String>,
174 rhs: impl Into<String>,
175 ) -> Self {
176 Self {
177 name: name.into(),
178 lhs: lhs.into(),
179 rhs: rhs.into(),
180 conditional: false,
181 }
182 }
183 pub fn conditional(
185 name: impl Into<String>,
186 lhs: impl Into<String>,
187 rhs: impl Into<String>,
188 ) -> Self {
189 Self {
190 name: name.into(),
191 lhs: lhs.into(),
192 rhs: rhs.into(),
193 conditional: true,
194 }
195 }
196 pub fn display(&self) -> String {
198 format!("{}: {} → {}", self.name, self.lhs, self.rhs)
199 }
200}
201#[allow(dead_code)]
203#[derive(Debug, Clone, Default)]
204pub struct TypeClassStats {
205 pub cache_hits: u64,
207 pub cache_misses: u64,
209 pub total_lookups: u64,
211 pub instances_registered: u64,
213 pub classes_registered: u64,
215}
216impl TypeClassStats {
217 #[allow(dead_code)]
219 pub fn new() -> Self {
220 Self::default()
221 }
222 #[allow(dead_code)]
224 pub fn hit_rate(&self) -> f64 {
225 if self.total_lookups == 0 {
226 1.0
227 } else {
228 self.cache_hits as f64 / self.total_lookups as f64
229 }
230 }
231 #[allow(dead_code)]
233 pub fn merge(&mut self, other: &Self) {
234 self.cache_hits += other.cache_hits;
235 self.cache_misses += other.cache_misses;
236 self.total_lookups += other.total_lookups;
237 self.instances_registered += other.instances_registered;
238 self.classes_registered += other.classes_registered;
239 }
240}
241#[allow(dead_code)]
243pub struct RawFnPtr {
244 ptr: usize,
246 arity: usize,
247 name: String,
248}
249#[allow(dead_code)]
250impl RawFnPtr {
251 pub fn new(ptr: usize, arity: usize, name: impl Into<String>) -> Self {
253 Self {
254 ptr,
255 arity,
256 name: name.into(),
257 }
258 }
259 pub fn arity(&self) -> usize {
261 self.arity
262 }
263 pub fn name(&self) -> &str {
265 &self.name
266 }
267 pub fn raw(&self) -> usize {
269 self.ptr
270 }
271}
272#[allow(dead_code)]
274pub struct SmallMap<K: Ord + Clone, V: Clone> {
275 entries: Vec<(K, V)>,
276}
277#[allow(dead_code)]
278impl<K: Ord + Clone, V: Clone> SmallMap<K, V> {
279 pub fn new() -> Self {
281 Self {
282 entries: Vec::new(),
283 }
284 }
285 pub fn insert(&mut self, key: K, val: V) {
287 match self.entries.binary_search_by_key(&&key, |(k, _)| k) {
288 Ok(i) => self.entries[i].1 = val,
289 Err(i) => self.entries.insert(i, (key, val)),
290 }
291 }
292 pub fn get(&self, key: &K) -> Option<&V> {
294 self.entries
295 .binary_search_by_key(&key, |(k, _)| k)
296 .ok()
297 .map(|i| &self.entries[i].1)
298 }
299 pub fn len(&self) -> usize {
301 self.entries.len()
302 }
303 pub fn is_empty(&self) -> bool {
305 self.entries.is_empty()
306 }
307 pub fn keys(&self) -> Vec<&K> {
309 self.entries.iter().map(|(k, _)| k).collect()
310 }
311 pub fn values(&self) -> Vec<&V> {
313 self.entries.iter().map(|(_, v)| v).collect()
314 }
315}
316#[allow(dead_code)]
320#[derive(Debug, Default)]
321pub struct LayeredTypeClassRegistry {
322 layers: Vec<TypeClassRegistry>,
324 global: TypeClassRegistry,
326}
327impl LayeredTypeClassRegistry {
328 #[allow(dead_code)]
330 pub fn new() -> Self {
331 Self {
332 layers: Vec::new(),
333 global: TypeClassRegistry::new(),
334 }
335 }
336 #[allow(dead_code)]
338 pub fn push_layer(&mut self) {
339 self.layers.push(TypeClassRegistry::new());
340 }
341 #[allow(dead_code)]
343 pub fn pop_layer(&mut self) {
344 self.layers.pop();
345 }
346 #[allow(dead_code)]
348 pub fn add_instance(&mut self, inst: Instance) {
349 if let Some(top) = self.layers.last_mut() {
350 top.register_instance(inst);
351 } else {
352 self.global.register_instance(inst);
353 }
354 }
355 #[allow(dead_code)]
357 pub fn add_class(&mut self, class: TypeClass) {
358 self.global.register_class(class);
359 }
360 #[allow(dead_code)]
362 pub fn find_instance(&self, class: &Name, ty: &Expr) -> Option<&Instance> {
363 for layer in self.layers.iter().rev() {
364 let found = layer.find_instances(class, ty);
365 if let Some(inst) = found.into_iter().next() {
366 return Some(inst);
367 }
368 }
369 self.global.find_instances(class, ty).into_iter().next()
370 }
371 #[allow(dead_code)]
373 pub fn depth(&self) -> usize {
374 self.layers.len()
375 }
376 #[allow(dead_code)]
378 pub fn total_instances(&self) -> usize {
379 let layer_total: usize = self.layers.iter().map(|l| l.instances.len()).sum();
380 layer_total + self.global.instances.len()
381 }
382}
383#[allow(dead_code)]
385pub struct FlatSubstitution {
386 pairs: Vec<(String, String)>,
387}
388#[allow(dead_code)]
389impl FlatSubstitution {
390 pub fn new() -> Self {
392 Self { pairs: Vec::new() }
393 }
394 pub fn add(&mut self, from: impl Into<String>, to: impl Into<String>) {
396 self.pairs.push((from.into(), to.into()));
397 }
398 pub fn apply(&self, s: &str) -> String {
400 let mut result = s.to_string();
401 for (from, to) in &self.pairs {
402 result = result.replace(from.as_str(), to.as_str());
403 }
404 result
405 }
406 pub fn len(&self) -> usize {
408 self.pairs.len()
409 }
410 pub fn is_empty(&self) -> bool {
412 self.pairs.is_empty()
413 }
414}
415#[derive(Clone, Debug, Default)]
417pub struct TypeClassRegistry {
418 pub(super) classes: HashMap<String, TypeClass>,
420 pub(super) instances: Vec<Instance>,
422 instance_cache: HashMap<(String, String), usize>,
424}
425impl TypeClassRegistry {
426 pub fn new() -> Self {
428 Self {
429 classes: HashMap::new(),
430 instances: Vec::new(),
431 instance_cache: HashMap::new(),
432 }
433 }
434 pub fn register_class(&mut self, class: TypeClass) {
436 self.classes.insert(class.name.to_string(), class);
437 }
438 pub fn get_class(&self, name: &Name) -> Option<&TypeClass> {
440 self.classes.get(&name.to_string())
441 }
442 pub fn is_class(&self, name: &Name) -> bool {
444 self.classes.contains_key(&name.to_string())
445 }
446 pub fn class_count(&self) -> usize {
448 self.classes.len()
449 }
450 pub fn class_names(&self) -> impl Iterator<Item = &String> {
452 self.classes.keys()
453 }
454 pub fn subclasses_of(&self, super_name: &Name) -> Vec<&TypeClass> {
456 self.classes
457 .values()
458 .filter(|c| c.has_super(super_name))
459 .collect()
460 }
461 pub fn register_instance(&mut self, instance: Instance) {
463 self.instance_cache
464 .remove(&(instance.class.to_string(), format!("{:?}", instance.ty)));
465 self.instances.push(instance);
466 }
467 pub fn find_instances(&self, class: &Name, ty: &Expr) -> Vec<&Instance> {
469 self.instances
470 .iter()
471 .filter(|inst| &inst.class == class && instances_match(ty, &inst.ty))
472 .collect()
473 }
474 pub fn find_best_instance(&self, class: &Name, ty: &Expr) -> InstanceSearchResult {
476 let mut candidates: Vec<&Instance> = self.find_instances(class, ty);
477 if candidates.is_empty() {
478 return InstanceSearchResult::NotFound;
479 }
480 candidates.sort_by_key(|i| i.priority);
481 let best_priority = candidates[0].priority;
482 let top: Vec<&Instance> = candidates
483 .iter()
484 .filter(|i| i.priority == best_priority)
485 .copied()
486 .collect();
487 if top.len() == 1 {
488 InstanceSearchResult::Found(top[0].clone())
489 } else {
490 InstanceSearchResult::Ambiguous(top.into_iter().cloned().collect())
491 }
492 }
493 pub fn instance_count(&self) -> usize {
495 self.instances.len()
496 }
497 pub fn clear_local_instances(&mut self) {
499 self.instances.retain(|i| !i.is_local);
500 self.instance_cache.clear();
501 }
502 pub fn instances_for_class(&self, class: &Name) -> Vec<&Instance> {
504 let mut result: Vec<&Instance> = self
505 .instances
506 .iter()
507 .filter(|i| &i.class == class)
508 .collect();
509 result.sort_by_key(|i| i.priority);
510 result
511 }
512 pub fn filter_instances<F>(&self, predicate: F) -> Vec<&Instance>
514 where
515 F: Fn(&Instance) -> bool,
516 {
517 self.instances.iter().filter(|i| predicate(i)).collect()
518 }
519 pub fn method_projection(&self, class: &Name, method: &Name) -> Option<Expr> {
521 let cls = self.get_class(class)?;
522 let m = cls.find_method(method)?;
523 Some(build_method_projection(class, method, m.index))
524 }
525 pub fn summary(&self) -> String {
527 format!(
528 "TypeClassRegistry {{ classes: {}, instances: {} }}",
529 self.classes.len(),
530 self.instances.len()
531 )
532 }
533}
534impl TypeClassRegistry {
535 pub fn snapshot(&self) -> RegistrySnapshot {
537 RegistrySnapshot {
538 instance_count: self.instances.len(),
539 }
540 }
541 pub fn restore(&mut self, snapshot: RegistrySnapshot) {
543 self.instances.truncate(snapshot.instance_count);
544 self.instance_cache.clear();
545 }
546}
547#[allow(dead_code)]
549pub struct TransformStat {
550 before: StatSummary,
551 after: StatSummary,
552}
553#[allow(dead_code)]
554impl TransformStat {
555 pub fn new() -> Self {
557 Self {
558 before: StatSummary::new(),
559 after: StatSummary::new(),
560 }
561 }
562 pub fn record_before(&mut self, v: f64) {
564 self.before.record(v);
565 }
566 pub fn record_after(&mut self, v: f64) {
568 self.after.record(v);
569 }
570 pub fn mean_ratio(&self) -> Option<f64> {
572 let b = self.before.mean()?;
573 let a = self.after.mean()?;
574 if b.abs() < f64::EPSILON {
575 return None;
576 }
577 Some(a / b)
578 }
579}
580#[allow(dead_code)]
582pub struct PathBuf {
583 components: Vec<String>,
584}
585#[allow(dead_code)]
586impl PathBuf {
587 pub fn new() -> Self {
589 Self {
590 components: Vec::new(),
591 }
592 }
593 pub fn push(&mut self, comp: impl Into<String>) {
595 self.components.push(comp.into());
596 }
597 pub fn pop(&mut self) {
599 self.components.pop();
600 }
601 pub fn as_str(&self) -> String {
603 self.components.join("/")
604 }
605 pub fn depth(&self) -> usize {
607 self.components.len()
608 }
609 pub fn clear(&mut self) {
611 self.components.clear();
612 }
613}
614#[derive(Debug)]
616pub struct RegistrySnapshot {
617 instance_count: usize,
618}
619#[allow(dead_code)]
621pub struct RewriteRuleSet {
622 rules: Vec<RewriteRule>,
623}
624#[allow(dead_code)]
625impl RewriteRuleSet {
626 pub fn new() -> Self {
628 Self { rules: Vec::new() }
629 }
630 pub fn add(&mut self, rule: RewriteRule) {
632 self.rules.push(rule);
633 }
634 pub fn len(&self) -> usize {
636 self.rules.len()
637 }
638 pub fn is_empty(&self) -> bool {
640 self.rules.is_empty()
641 }
642 pub fn conditional_rules(&self) -> Vec<&RewriteRule> {
644 self.rules.iter().filter(|r| r.conditional).collect()
645 }
646 pub fn unconditional_rules(&self) -> Vec<&RewriteRule> {
648 self.rules.iter().filter(|r| !r.conditional).collect()
649 }
650 pub fn get(&self, name: &str) -> Option<&RewriteRule> {
652 self.rules.iter().find(|r| r.name == name)
653 }
654}
655#[allow(dead_code)]
657pub struct SparseVec<T: Default + Clone + PartialEq> {
658 entries: std::collections::HashMap<usize, T>,
659 default_: T,
660 logical_len: usize,
661}
662#[allow(dead_code)]
663impl<T: Default + Clone + PartialEq> SparseVec<T> {
664 pub fn new(len: usize) -> Self {
666 Self {
667 entries: std::collections::HashMap::new(),
668 default_: T::default(),
669 logical_len: len,
670 }
671 }
672 pub fn set(&mut self, idx: usize, val: T) {
674 if val == self.default_ {
675 self.entries.remove(&idx);
676 } else {
677 self.entries.insert(idx, val);
678 }
679 }
680 pub fn get(&self, idx: usize) -> &T {
682 self.entries.get(&idx).unwrap_or(&self.default_)
683 }
684 pub fn len(&self) -> usize {
686 self.logical_len
687 }
688 pub fn is_empty(&self) -> bool {
690 self.len() == 0
691 }
692 pub fn nnz(&self) -> usize {
694 self.entries.len()
695 }
696}
697#[allow(dead_code)]
699pub struct NonEmptyVec<T> {
700 head: T,
701 tail: Vec<T>,
702}
703#[allow(dead_code)]
704impl<T> NonEmptyVec<T> {
705 pub fn singleton(val: T) -> Self {
707 Self {
708 head: val,
709 tail: Vec::new(),
710 }
711 }
712 pub fn push(&mut self, val: T) {
714 self.tail.push(val);
715 }
716 pub fn first(&self) -> &T {
718 &self.head
719 }
720 pub fn last(&self) -> &T {
722 self.tail.last().unwrap_or(&self.head)
723 }
724 pub fn len(&self) -> usize {
726 1 + self.tail.len()
727 }
728 pub fn is_empty(&self) -> bool {
730 self.len() == 0
731 }
732 pub fn to_vec(&self) -> Vec<&T> {
734 let mut v = vec![&self.head];
735 v.extend(self.tail.iter());
736 v
737 }
738}
739#[allow(dead_code)]
741pub struct SlidingSum {
742 window: Vec<f64>,
743 capacity: usize,
744 pos: usize,
745 sum: f64,
746 count: usize,
747}
748#[allow(dead_code)]
749impl SlidingSum {
750 pub fn new(capacity: usize) -> Self {
752 Self {
753 window: vec![0.0; capacity],
754 capacity,
755 pos: 0,
756 sum: 0.0,
757 count: 0,
758 }
759 }
760 pub fn push(&mut self, val: f64) {
762 let oldest = self.window[self.pos];
763 self.sum -= oldest;
764 self.sum += val;
765 self.window[self.pos] = val;
766 self.pos = (self.pos + 1) % self.capacity;
767 if self.count < self.capacity {
768 self.count += 1;
769 }
770 }
771 pub fn sum(&self) -> f64 {
773 self.sum
774 }
775 pub fn mean(&self) -> Option<f64> {
777 if self.count == 0 {
778 None
779 } else {
780 Some(self.sum / self.count as f64)
781 }
782 }
783 pub fn count(&self) -> usize {
785 self.count
786 }
787}
788#[allow(dead_code)]
790pub struct WriteOnce<T> {
791 value: std::cell::Cell<Option<T>>,
792}
793#[allow(dead_code)]
794impl<T: Copy> WriteOnce<T> {
795 pub fn new() -> Self {
797 Self {
798 value: std::cell::Cell::new(None),
799 }
800 }
801 pub fn write(&self, val: T) -> bool {
803 if self.value.get().is_some() {
804 return false;
805 }
806 self.value.set(Some(val));
807 true
808 }
809 pub fn read(&self) -> Option<T> {
811 self.value.get()
812 }
813 pub fn is_written(&self) -> bool {
815 self.value.get().is_some()
816 }
817}
818#[allow(dead_code)]
820pub struct StackCalc {
821 stack: Vec<i64>,
822}
823#[allow(dead_code)]
824impl StackCalc {
825 pub fn new() -> Self {
827 Self { stack: Vec::new() }
828 }
829 pub fn push(&mut self, n: i64) {
831 self.stack.push(n);
832 }
833 fn apply_binary(&mut self, op: impl FnOnce(i64, i64) -> i64) -> Option<i64> {
837 let (rest_len, a, b) = match self.stack[..] {
838 [ref rest @ .., a, b] => (rest.len(), a, b),
839 _ => return None,
840 };
841 let value = op(a, b);
842 self.stack.truncate(rest_len);
843 self.stack.push(value);
844 Some(value)
845 }
846 pub fn add(&mut self) -> Option<i64> {
850 self.apply_binary(|a, b| a + b)
851 }
852 pub fn sub(&mut self) -> Option<i64> {
856 self.apply_binary(|a, b| a - b)
857 }
858 pub fn mul(&mut self) -> Option<i64> {
862 self.apply_binary(|a, b| a * b)
863 }
864 pub fn peek(&self) -> Option<i64> {
866 self.stack.last().copied()
867 }
868 pub fn depth(&self) -> usize {
870 self.stack.len()
871 }
872}
873#[allow(dead_code)]
875pub struct Stopwatch {
876 start: crate::wall_clock::Instant,
877 splits: Vec<f64>,
878}
879#[allow(dead_code)]
880impl Stopwatch {
881 pub fn start() -> Self {
883 Self {
884 start: crate::wall_clock::Instant::now(),
885 splits: Vec::new(),
886 }
887 }
888 pub fn split(&mut self) {
890 self.splits.push(self.elapsed_ms());
891 }
892 pub fn elapsed_ms(&self) -> f64 {
894 self.start.elapsed().as_secs_f64() * 1000.0
895 }
896 pub fn splits(&self) -> &[f64] {
898 &self.splits
899 }
900 pub fn num_splits(&self) -> usize {
902 self.splits.len()
903 }
904}
905#[allow(dead_code)]
907pub enum Either2<A, B> {
908 First(A),
910 Second(B),
912}
913#[allow(dead_code)]
914impl<A, B> Either2<A, B> {
915 pub fn is_first(&self) -> bool {
917 matches!(self, Either2::First(_))
918 }
919 pub fn is_second(&self) -> bool {
921 matches!(self, Either2::Second(_))
922 }
923 pub fn first(self) -> Option<A> {
925 match self {
926 Either2::First(a) => Some(a),
927 _ => None,
928 }
929 }
930 pub fn second(self) -> Option<B> {
932 match self {
933 Either2::Second(b) => Some(b),
934 _ => None,
935 }
936 }
937 pub fn map_first<C, F: FnOnce(A) -> C>(self, f: F) -> Either2<C, B> {
939 match self {
940 Either2::First(a) => Either2::First(f(a)),
941 Either2::Second(b) => Either2::Second(b),
942 }
943 }
944}
945#[allow(dead_code)]
947pub struct ConfigNode {
948 key: String,
949 value: Option<String>,
950 children: Vec<ConfigNode>,
951}
952#[allow(dead_code)]
953impl ConfigNode {
954 pub fn leaf(key: impl Into<String>, value: impl Into<String>) -> Self {
956 Self {
957 key: key.into(),
958 value: Some(value.into()),
959 children: Vec::new(),
960 }
961 }
962 pub fn section(key: impl Into<String>) -> Self {
964 Self {
965 key: key.into(),
966 value: None,
967 children: Vec::new(),
968 }
969 }
970 pub fn add_child(&mut self, child: ConfigNode) {
972 self.children.push(child);
973 }
974 pub fn key(&self) -> &str {
976 &self.key
977 }
978 pub fn value(&self) -> Option<&str> {
980 self.value.as_deref()
981 }
982 pub fn num_children(&self) -> usize {
984 self.children.len()
985 }
986 pub fn lookup(&self, path: &str) -> Option<&str> {
988 let mut parts = path.splitn(2, '.');
989 let head = parts.next()?;
990 let tail = parts.next();
991 if head != self.key {
992 return None;
993 }
994 match tail {
995 None => self.value.as_deref(),
996 Some(rest) => self.children.iter().find_map(|c| c.lookup_relative(rest)),
997 }
998 }
999 fn lookup_relative(&self, path: &str) -> Option<&str> {
1000 let mut parts = path.splitn(2, '.');
1001 let head = parts.next()?;
1002 let tail = parts.next();
1003 if head != self.key {
1004 return None;
1005 }
1006 match tail {
1007 None => self.value.as_deref(),
1008 Some(rest) => self.children.iter().find_map(|c| c.lookup_relative(rest)),
1009 }
1010 }
1011}
1012#[derive(Debug)]
1014pub struct NullResolver;
1015#[allow(dead_code)]
1017pub struct WindowIterator<'a, T> {
1018 pub(super) data: &'a [T],
1019 pub(super) pos: usize,
1020 pub(super) window: usize,
1021}
1022#[allow(dead_code)]
1023impl<'a, T> WindowIterator<'a, T> {
1024 pub fn new(data: &'a [T], window: usize) -> Self {
1026 Self {
1027 data,
1028 pos: 0,
1029 window,
1030 }
1031 }
1032}
1033#[allow(dead_code)]
1035pub struct StatSummary {
1036 count: u64,
1037 sum: f64,
1038 min: f64,
1039 max: f64,
1040}
1041#[allow(dead_code)]
1042impl StatSummary {
1043 pub fn new() -> Self {
1045 Self {
1046 count: 0,
1047 sum: 0.0,
1048 min: f64::INFINITY,
1049 max: f64::NEG_INFINITY,
1050 }
1051 }
1052 pub fn record(&mut self, val: f64) {
1054 self.count += 1;
1055 self.sum += val;
1056 if val < self.min {
1057 self.min = val;
1058 }
1059 if val > self.max {
1060 self.max = val;
1061 }
1062 }
1063 pub fn mean(&self) -> Option<f64> {
1065 if self.count == 0 {
1066 None
1067 } else {
1068 Some(self.sum / self.count as f64)
1069 }
1070 }
1071 pub fn min(&self) -> Option<f64> {
1073 if self.count == 0 {
1074 None
1075 } else {
1076 Some(self.min)
1077 }
1078 }
1079 pub fn max(&self) -> Option<f64> {
1081 if self.count == 0 {
1082 None
1083 } else {
1084 Some(self.max)
1085 }
1086 }
1087 pub fn count(&self) -> u64 {
1089 self.count
1090 }
1091}
1092#[allow(dead_code)]
1094pub struct FocusStack<T> {
1095 items: Vec<T>,
1096}
1097#[allow(dead_code)]
1098impl<T> FocusStack<T> {
1099 pub fn new() -> Self {
1101 Self { items: Vec::new() }
1102 }
1103 pub fn focus(&mut self, item: T) {
1105 self.items.push(item);
1106 }
1107 pub fn blur(&mut self) -> Option<T> {
1109 self.items.pop()
1110 }
1111 pub fn current(&self) -> Option<&T> {
1113 self.items.last()
1114 }
1115 pub fn depth(&self) -> usize {
1117 self.items.len()
1118 }
1119 pub fn is_empty(&self) -> bool {
1121 self.items.is_empty()
1122 }
1123}
1124#[allow(dead_code)]
1126pub struct TokenBucket {
1127 capacity: u64,
1128 tokens: u64,
1129 refill_per_ms: u64,
1130 last_refill: crate::wall_clock::Instant,
1131}
1132#[allow(dead_code)]
1133impl TokenBucket {
1134 pub fn new(capacity: u64, refill_per_ms: u64) -> Self {
1136 Self {
1137 capacity,
1138 tokens: capacity,
1139 refill_per_ms,
1140 last_refill: crate::wall_clock::Instant::now(),
1141 }
1142 }
1143 pub fn try_consume(&mut self, n: u64) -> bool {
1145 self.refill();
1146 if self.tokens >= n {
1147 self.tokens -= n;
1148 true
1149 } else {
1150 false
1151 }
1152 }
1153 fn refill(&mut self) {
1154 let now = crate::wall_clock::Instant::now();
1155 let elapsed_ms = now.duration_since(self.last_refill).as_millis() as u64;
1156 if elapsed_ms > 0 {
1157 let new_tokens = elapsed_ms * self.refill_per_ms;
1158 self.tokens = (self.tokens + new_tokens).min(self.capacity);
1159 self.last_refill = now;
1160 }
1161 }
1162 pub fn available(&self) -> u64 {
1164 self.tokens
1165 }
1166 pub fn capacity(&self) -> u64 {
1168 self.capacity
1169 }
1170}
1171#[allow(dead_code)]
1173#[derive(Clone, Debug, Default)]
1174pub struct InstanceImpl {
1175 impls: Vec<MethodImpl>,
1177}
1178impl InstanceImpl {
1179 #[allow(dead_code)]
1181 pub fn new() -> Self {
1182 Self::default()
1183 }
1184 #[allow(dead_code)]
1186 pub fn add(&mut self, impl_: MethodImpl) {
1187 self.impls.push(impl_);
1188 }
1189 #[allow(dead_code)]
1191 pub fn get(&self, method: &Name) -> Option<&MethodImpl> {
1192 self.impls.iter().find(|m| &m.method_name == method)
1193 }
1194 #[allow(dead_code)]
1196 pub fn len(&self) -> usize {
1197 self.impls.len()
1198 }
1199 #[allow(dead_code)]
1201 pub fn is_empty(&self) -> bool {
1202 self.impls.is_empty()
1203 }
1204 #[allow(dead_code)]
1206 pub fn count_defaults(&self) -> usize {
1207 self.impls.iter().filter(|m| m.is_default).count()
1208 }
1209 #[allow(dead_code)]
1211 pub fn method_names(&self) -> Vec<&Name> {
1212 self.impls.iter().map(|m| &m.method_name).collect()
1213 }
1214}
1215#[allow(dead_code)]
1217pub struct TransitiveClosure {
1218 adj: Vec<Vec<usize>>,
1219 n: usize,
1220}
1221#[allow(dead_code)]
1222impl TransitiveClosure {
1223 pub fn new(n: usize) -> Self {
1225 Self {
1226 adj: vec![Vec::new(); n],
1227 n,
1228 }
1229 }
1230 pub fn add_edge(&mut self, from: usize, to: usize) {
1232 if from < self.n {
1233 self.adj[from].push(to);
1234 }
1235 }
1236 pub fn reachable_from(&self, start: usize) -> Vec<usize> {
1238 let mut visited = vec![false; self.n];
1239 let mut queue = std::collections::VecDeque::new();
1240 queue.push_back(start);
1241 while let Some(node) = queue.pop_front() {
1242 if node >= self.n || visited[node] {
1243 continue;
1244 }
1245 visited[node] = true;
1246 for &next in &self.adj[node] {
1247 queue.push_back(next);
1248 }
1249 }
1250 (0..self.n).filter(|&i| visited[i]).collect()
1251 }
1252 pub fn can_reach(&self, from: usize, to: usize) -> bool {
1254 self.reachable_from(from).contains(&to)
1255 }
1256}
1257#[allow(dead_code)]
1259pub struct SimpleDag {
1260 edges: Vec<Vec<usize>>,
1262}
1263#[allow(dead_code)]
1264impl SimpleDag {
1265 pub fn new(n: usize) -> Self {
1267 Self {
1268 edges: vec![Vec::new(); n],
1269 }
1270 }
1271 pub fn add_edge(&mut self, from: usize, to: usize) {
1273 if from < self.edges.len() {
1274 self.edges[from].push(to);
1275 }
1276 }
1277 pub fn successors(&self, node: usize) -> &[usize] {
1279 self.edges.get(node).map(|v| v.as_slice()).unwrap_or(&[])
1280 }
1281 pub fn can_reach(&self, from: usize, to: usize) -> bool {
1283 let mut visited = vec![false; self.edges.len()];
1284 self.dfs(from, to, &mut visited)
1285 }
1286 fn dfs(&self, cur: usize, target: usize, visited: &mut Vec<bool>) -> bool {
1287 if cur == target {
1288 return true;
1289 }
1290 if cur >= visited.len() || visited[cur] {
1291 return false;
1292 }
1293 visited[cur] = true;
1294 for &next in self.successors(cur) {
1295 if self.dfs(next, target, visited) {
1296 return true;
1297 }
1298 }
1299 false
1300 }
1301 pub fn topological_sort(&self) -> Option<Vec<usize>> {
1303 let n = self.edges.len();
1304 let mut in_degree = vec![0usize; n];
1305 for succs in &self.edges {
1306 for &s in succs {
1307 if s < n {
1308 in_degree[s] += 1;
1309 }
1310 }
1311 }
1312 let mut queue: std::collections::VecDeque<usize> =
1313 (0..n).filter(|&i| in_degree[i] == 0).collect();
1314 let mut order = Vec::new();
1315 while let Some(node) = queue.pop_front() {
1316 order.push(node);
1317 for &s in self.successors(node) {
1318 if s < n {
1319 in_degree[s] -= 1;
1320 if in_degree[s] == 0 {
1321 queue.push_back(s);
1322 }
1323 }
1324 }
1325 }
1326 if order.len() == n {
1327 Some(order)
1328 } else {
1329 None
1330 }
1331 }
1332 pub fn num_nodes(&self) -> usize {
1334 self.edges.len()
1335 }
1336}
1337#[derive(Clone, Debug)]
1342pub struct TypeClass {
1343 pub name: Name,
1345 pub params: Vec<Name>,
1347 pub ty: Expr,
1349 pub methods: Vec<Method>,
1351 pub super_classes: Vec<Name>,
1353 pub is_prop: bool,
1355}
1356impl TypeClass {
1357 pub fn new(name: Name, params: Vec<Name>, ty: Expr) -> Self {
1359 Self {
1360 name,
1361 params,
1362 ty,
1363 methods: Vec::new(),
1364 super_classes: Vec::new(),
1365 is_prop: false,
1366 }
1367 }
1368 pub fn add_method(&mut self, method: Method) {
1370 self.methods.push(method);
1371 }
1372 pub fn add_super(&mut self, super_name: Name) {
1374 self.super_classes.push(super_name);
1375 }
1376 pub fn mark_prop(mut self) -> Self {
1378 self.is_prop = true;
1379 self
1380 }
1381 pub fn find_method(&self, name: &Name) -> Option<&Method> {
1383 self.methods.iter().find(|m| &m.name == name)
1384 }
1385 pub fn has_super(&self, name: &Name) -> bool {
1387 self.super_classes.contains(name)
1388 }
1389 pub fn method_count(&self) -> usize {
1391 self.methods.len()
1392 }
1393 pub fn is_empty(&self) -> bool {
1395 self.methods.is_empty()
1396 }
1397 pub fn method_names(&self) -> impl Iterator<Item = &Name> {
1399 self.methods.iter().map(|m| &m.name)
1400 }
1401 pub fn has_super_classes(&self) -> bool {
1403 !self.super_classes.is_empty()
1404 }
1405 pub fn arity(&self) -> usize {
1407 self.params.len()
1408 }
1409}
1410#[derive(Clone, Debug)]
1414pub struct Instance {
1415 pub class: Name,
1417 pub ty: Expr,
1419 pub priority: i32,
1421 pub methods: HashMap<String, Expr>,
1423 pub instance_name: Option<Name>,
1425 pub is_local: bool,
1427}
1428impl Instance {
1429 pub fn new(class: Name, ty: Expr) -> Self {
1431 Self {
1432 class,
1433 ty,
1434 priority: 100,
1435 methods: HashMap::new(),
1436 instance_name: None,
1437 is_local: false,
1438 }
1439 }
1440 pub fn named(class: Name, ty: Expr, name: Name) -> Self {
1442 Self {
1443 class,
1444 ty,
1445 priority: 100,
1446 methods: HashMap::new(),
1447 instance_name: Some(name),
1448 is_local: false,
1449 }
1450 }
1451 pub fn with_priority(mut self, priority: i32) -> Self {
1453 self.priority = priority;
1454 self
1455 }
1456 pub fn as_local(mut self) -> Self {
1458 self.is_local = true;
1459 self
1460 }
1461 pub fn add_method_impl(&mut self, method_name: impl Into<String>, impl_expr: Expr) {
1463 self.methods.insert(method_name.into(), impl_expr);
1464 }
1465 pub fn get_method_impl(&self, method_name: &str) -> Option<&Expr> {
1467 self.methods.get(method_name)
1468 }
1469 pub fn implements_all(&self, class: &TypeClass) -> bool {
1471 class
1472 .methods
1473 .iter()
1474 .all(|m| self.methods.contains_key(&m.name.to_string()))
1475 }
1476 pub fn implemented_count(&self) -> usize {
1478 self.methods.len()
1479 }
1480 pub fn is_named(&self) -> bool {
1482 self.instance_name.is_some()
1483 }
1484}
1485#[derive(Clone, Debug)]
1487pub struct Method {
1488 pub name: Name,
1490 pub ty: Expr,
1492 pub has_default: bool,
1494 pub index: usize,
1496}
1497impl Method {
1498 pub fn new(name: Name, ty: Expr, index: usize) -> Self {
1500 Self {
1501 name,
1502 ty,
1503 has_default: false,
1504 index,
1505 }
1506 }
1507 pub fn with_default(name: Name, ty: Expr, index: usize) -> Self {
1509 Self {
1510 name,
1511 ty,
1512 has_default: true,
1513 index,
1514 }
1515 }
1516 pub fn set_default(mut self) -> Self {
1518 self.has_default = true;
1519 self
1520 }
1521}
1522#[derive(Clone, Debug, PartialEq, Eq)]
1524pub struct ClassEdge {
1525 pub parent: Name,
1527 pub child: Name,
1529}
1530impl ClassEdge {
1531 pub fn new(parent: Name, child: Name) -> Self {
1533 Self { parent, child }
1534 }
1535}
1536#[allow(dead_code)]
1538pub struct LabelSet {
1539 labels: Vec<String>,
1540}
1541#[allow(dead_code)]
1542impl LabelSet {
1543 pub fn new() -> Self {
1545 Self { labels: Vec::new() }
1546 }
1547 pub fn add(&mut self, label: impl Into<String>) {
1549 let s = label.into();
1550 if !self.labels.contains(&s) {
1551 self.labels.push(s);
1552 }
1553 }
1554 pub fn has(&self, label: &str) -> bool {
1556 self.labels.iter().any(|l| l == label)
1557 }
1558 pub fn count(&self) -> usize {
1560 self.labels.len()
1561 }
1562 pub fn all(&self) -> &[String] {
1564 &self.labels
1565 }
1566}
1567#[allow(dead_code)]
1569#[derive(Clone, Debug)]
1570pub struct MethodImpl {
1571 pub method_name: Name,
1573 pub impl_expr: Expr,
1575 pub is_default: bool,
1577}
1578impl MethodImpl {
1579 #[allow(dead_code)]
1581 pub fn custom(method: Name, expr: Expr) -> Self {
1582 Self {
1583 method_name: method,
1584 impl_expr: expr,
1585 is_default: false,
1586 }
1587 }
1588 #[allow(dead_code)]
1590 pub fn default_impl(method: Name, expr: Expr) -> Self {
1591 Self {
1592 method_name: method,
1593 impl_expr: expr,
1594 is_default: true,
1595 }
1596 }
1597}
1598#[derive(Clone, Debug)]
1600pub enum InstanceSearchResult {
1601 Found(Instance),
1603 Ambiguous(Vec<Instance>),
1605 NotFound,
1607}
1608impl InstanceSearchResult {
1609 pub fn is_found(&self) -> bool {
1611 matches!(self, InstanceSearchResult::Found(_))
1612 }
1613 pub fn is_ambiguous(&self) -> bool {
1615 matches!(self, InstanceSearchResult::Ambiguous(_))
1616 }
1617 pub fn into_instance(self) -> Option<Instance> {
1619 match self {
1620 InstanceSearchResult::Found(inst) => Some(inst),
1621 _ => None,
1622 }
1623 }
1624}