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 history: Vec<T>,
69}
70#[allow(dead_code)]
71impl<T: Clone> VersionedRecord<T> {
72 pub fn new(initial: T) -> Self {
74 Self {
75 history: vec![initial],
76 }
77 }
78 pub fn update(&mut self, val: T) {
80 self.history.push(val);
81 }
82 pub fn current(&self) -> &T {
84 self.history
85 .last()
86 .expect("VersionedRecord history is always non-empty after construction")
87 }
88 pub fn at_version(&self, n: usize) -> Option<&T> {
90 self.history.get(n)
91 }
92 pub fn version(&self) -> usize {
94 self.history.len() - 1
95 }
96 pub fn has_history(&self) -> bool {
98 self.history.len() > 1
99 }
100}
101#[allow(dead_code)]
103#[allow(missing_docs)]
104pub enum DecisionNode {
105 Leaf(String),
107 Branch {
109 key: String,
110 val: String,
111 yes_branch: Box<DecisionNode>,
112 no_branch: Box<DecisionNode>,
113 },
114}
115#[allow(dead_code)]
116impl DecisionNode {
117 pub fn evaluate(&self, ctx: &std::collections::HashMap<String, String>) -> &str {
119 match self {
120 DecisionNode::Leaf(action) => action.as_str(),
121 DecisionNode::Branch {
122 key,
123 val,
124 yes_branch,
125 no_branch,
126 } => {
127 let actual = ctx.get(key).map(|s| s.as_str()).unwrap_or("");
128 if actual == val.as_str() {
129 yes_branch.evaluate(ctx)
130 } else {
131 no_branch.evaluate(ctx)
132 }
133 }
134 }
135 }
136 pub fn depth(&self) -> usize {
138 match self {
139 DecisionNode::Leaf(_) => 0,
140 DecisionNode::Branch {
141 yes_branch,
142 no_branch,
143 ..
144 } => 1 + yes_branch.depth().max(no_branch.depth()),
145 }
146 }
147}
148#[allow(dead_code)]
150#[allow(missing_docs)]
151pub struct RewriteRule {
152 pub name: String,
154 pub lhs: String,
156 pub rhs: String,
158 pub conditional: bool,
160}
161#[allow(dead_code)]
162impl RewriteRule {
163 pub fn unconditional(
165 name: impl Into<String>,
166 lhs: impl Into<String>,
167 rhs: impl Into<String>,
168 ) -> Self {
169 Self {
170 name: name.into(),
171 lhs: lhs.into(),
172 rhs: rhs.into(),
173 conditional: false,
174 }
175 }
176 pub fn conditional(
178 name: impl Into<String>,
179 lhs: impl Into<String>,
180 rhs: impl Into<String>,
181 ) -> Self {
182 Self {
183 name: name.into(),
184 lhs: lhs.into(),
185 rhs: rhs.into(),
186 conditional: true,
187 }
188 }
189 pub fn display(&self) -> String {
191 format!("{}: {} → {}", self.name, self.lhs, self.rhs)
192 }
193}
194#[allow(dead_code)]
196#[derive(Debug, Clone, Default)]
197pub struct TypeClassStats {
198 pub cache_hits: u64,
200 pub cache_misses: u64,
202 pub total_lookups: u64,
204 pub instances_registered: u64,
206 pub classes_registered: u64,
208}
209impl TypeClassStats {
210 #[allow(dead_code)]
212 pub fn new() -> Self {
213 Self::default()
214 }
215 #[allow(dead_code)]
217 pub fn hit_rate(&self) -> f64 {
218 if self.total_lookups == 0 {
219 1.0
220 } else {
221 self.cache_hits as f64 / self.total_lookups as f64
222 }
223 }
224 #[allow(dead_code)]
226 pub fn merge(&mut self, other: &Self) {
227 self.cache_hits += other.cache_hits;
228 self.cache_misses += other.cache_misses;
229 self.total_lookups += other.total_lookups;
230 self.instances_registered += other.instances_registered;
231 self.classes_registered += other.classes_registered;
232 }
233}
234#[allow(dead_code)]
236pub struct RawFnPtr {
237 ptr: usize,
239 arity: usize,
240 name: String,
241}
242#[allow(dead_code)]
243impl RawFnPtr {
244 pub fn new(ptr: usize, arity: usize, name: impl Into<String>) -> Self {
246 Self {
247 ptr,
248 arity,
249 name: name.into(),
250 }
251 }
252 pub fn arity(&self) -> usize {
254 self.arity
255 }
256 pub fn name(&self) -> &str {
258 &self.name
259 }
260 pub fn raw(&self) -> usize {
262 self.ptr
263 }
264}
265#[allow(dead_code)]
267pub struct SmallMap<K: Ord + Clone, V: Clone> {
268 entries: Vec<(K, V)>,
269}
270#[allow(dead_code)]
271impl<K: Ord + Clone, V: Clone> SmallMap<K, V> {
272 pub fn new() -> Self {
274 Self {
275 entries: Vec::new(),
276 }
277 }
278 pub fn insert(&mut self, key: K, val: V) {
280 match self.entries.binary_search_by_key(&&key, |(k, _)| k) {
281 Ok(i) => self.entries[i].1 = val,
282 Err(i) => self.entries.insert(i, (key, val)),
283 }
284 }
285 pub fn get(&self, key: &K) -> Option<&V> {
287 self.entries
288 .binary_search_by_key(&key, |(k, _)| k)
289 .ok()
290 .map(|i| &self.entries[i].1)
291 }
292 pub fn len(&self) -> usize {
294 self.entries.len()
295 }
296 pub fn is_empty(&self) -> bool {
298 self.entries.is_empty()
299 }
300 pub fn keys(&self) -> Vec<&K> {
302 self.entries.iter().map(|(k, _)| k).collect()
303 }
304 pub fn values(&self) -> Vec<&V> {
306 self.entries.iter().map(|(_, v)| v).collect()
307 }
308}
309#[allow(dead_code)]
313#[derive(Debug, Default)]
314pub struct LayeredTypeClassRegistry {
315 layers: Vec<TypeClassRegistry>,
317 global: TypeClassRegistry,
319}
320impl LayeredTypeClassRegistry {
321 #[allow(dead_code)]
323 pub fn new() -> Self {
324 Self {
325 layers: Vec::new(),
326 global: TypeClassRegistry::new(),
327 }
328 }
329 #[allow(dead_code)]
331 pub fn push_layer(&mut self) {
332 self.layers.push(TypeClassRegistry::new());
333 }
334 #[allow(dead_code)]
336 pub fn pop_layer(&mut self) {
337 self.layers.pop();
338 }
339 #[allow(dead_code)]
341 pub fn add_instance(&mut self, inst: Instance) {
342 if let Some(top) = self.layers.last_mut() {
343 top.register_instance(inst);
344 } else {
345 self.global.register_instance(inst);
346 }
347 }
348 #[allow(dead_code)]
350 pub fn add_class(&mut self, class: TypeClass) {
351 self.global.register_class(class);
352 }
353 #[allow(dead_code)]
355 pub fn find_instance(&self, class: &Name, ty: &Expr) -> Option<&Instance> {
356 for layer in self.layers.iter().rev() {
357 let found = layer.find_instances(class, ty);
358 if let Some(inst) = found.into_iter().next() {
359 return Some(inst);
360 }
361 }
362 self.global.find_instances(class, ty).into_iter().next()
363 }
364 #[allow(dead_code)]
366 pub fn depth(&self) -> usize {
367 self.layers.len()
368 }
369 #[allow(dead_code)]
371 pub fn total_instances(&self) -> usize {
372 let layer_total: usize = self.layers.iter().map(|l| l.instances.len()).sum();
373 layer_total + self.global.instances.len()
374 }
375}
376#[allow(dead_code)]
378pub struct FlatSubstitution {
379 pairs: Vec<(String, String)>,
380}
381#[allow(dead_code)]
382impl FlatSubstitution {
383 pub fn new() -> Self {
385 Self { pairs: Vec::new() }
386 }
387 pub fn add(&mut self, from: impl Into<String>, to: impl Into<String>) {
389 self.pairs.push((from.into(), to.into()));
390 }
391 pub fn apply(&self, s: &str) -> String {
393 let mut result = s.to_string();
394 for (from, to) in &self.pairs {
395 result = result.replace(from.as_str(), to.as_str());
396 }
397 result
398 }
399 pub fn len(&self) -> usize {
401 self.pairs.len()
402 }
403 pub fn is_empty(&self) -> bool {
405 self.pairs.is_empty()
406 }
407}
408#[derive(Clone, Debug, Default)]
410pub struct TypeClassRegistry {
411 pub(super) classes: HashMap<String, TypeClass>,
413 pub(super) instances: Vec<Instance>,
415 instance_cache: HashMap<(String, String), usize>,
417}
418impl TypeClassRegistry {
419 pub fn new() -> Self {
421 Self {
422 classes: HashMap::new(),
423 instances: Vec::new(),
424 instance_cache: HashMap::new(),
425 }
426 }
427 pub fn register_class(&mut self, class: TypeClass) {
429 self.classes.insert(class.name.to_string(), class);
430 }
431 pub fn get_class(&self, name: &Name) -> Option<&TypeClass> {
433 self.classes.get(&name.to_string())
434 }
435 pub fn is_class(&self, name: &Name) -> bool {
437 self.classes.contains_key(&name.to_string())
438 }
439 pub fn class_count(&self) -> usize {
441 self.classes.len()
442 }
443 pub fn class_names(&self) -> impl Iterator<Item = &String> {
445 self.classes.keys()
446 }
447 pub fn subclasses_of(&self, super_name: &Name) -> Vec<&TypeClass> {
449 self.classes
450 .values()
451 .filter(|c| c.has_super(super_name))
452 .collect()
453 }
454 pub fn register_instance(&mut self, instance: Instance) {
456 self.instance_cache
457 .remove(&(instance.class.to_string(), format!("{:?}", instance.ty)));
458 self.instances.push(instance);
459 }
460 pub fn find_instances(&self, class: &Name, ty: &Expr) -> Vec<&Instance> {
462 self.instances
463 .iter()
464 .filter(|inst| &inst.class == class && instances_match(ty, &inst.ty))
465 .collect()
466 }
467 pub fn find_best_instance(&self, class: &Name, ty: &Expr) -> InstanceSearchResult {
469 let mut candidates: Vec<&Instance> = self.find_instances(class, ty);
470 if candidates.is_empty() {
471 return InstanceSearchResult::NotFound;
472 }
473 candidates.sort_by_key(|i| i.priority);
474 let best_priority = candidates[0].priority;
475 let top: Vec<&Instance> = candidates
476 .iter()
477 .filter(|i| i.priority == best_priority)
478 .copied()
479 .collect();
480 if top.len() == 1 {
481 InstanceSearchResult::Found(top[0].clone())
482 } else {
483 InstanceSearchResult::Ambiguous(top.into_iter().cloned().collect())
484 }
485 }
486 pub fn instance_count(&self) -> usize {
488 self.instances.len()
489 }
490 pub fn clear_local_instances(&mut self) {
492 self.instances.retain(|i| !i.is_local);
493 self.instance_cache.clear();
494 }
495 pub fn instances_for_class(&self, class: &Name) -> Vec<&Instance> {
497 let mut result: Vec<&Instance> = self
498 .instances
499 .iter()
500 .filter(|i| &i.class == class)
501 .collect();
502 result.sort_by_key(|i| i.priority);
503 result
504 }
505 pub fn filter_instances<F>(&self, predicate: F) -> Vec<&Instance>
507 where
508 F: Fn(&Instance) -> bool,
509 {
510 self.instances.iter().filter(|i| predicate(i)).collect()
511 }
512 pub fn method_projection(&self, class: &Name, method: &Name) -> Option<Expr> {
514 let cls = self.get_class(class)?;
515 let m = cls.find_method(method)?;
516 Some(build_method_projection(class, method, m.index))
517 }
518 pub fn summary(&self) -> String {
520 format!(
521 "TypeClassRegistry {{ classes: {}, instances: {} }}",
522 self.classes.len(),
523 self.instances.len()
524 )
525 }
526}
527impl TypeClassRegistry {
528 pub fn snapshot(&self) -> RegistrySnapshot {
530 RegistrySnapshot {
531 instance_count: self.instances.len(),
532 }
533 }
534 pub fn restore(&mut self, snapshot: RegistrySnapshot) {
536 self.instances.truncate(snapshot.instance_count);
537 self.instance_cache.clear();
538 }
539}
540#[allow(dead_code)]
542pub struct TransformStat {
543 before: StatSummary,
544 after: StatSummary,
545}
546#[allow(dead_code)]
547impl TransformStat {
548 pub fn new() -> Self {
550 Self {
551 before: StatSummary::new(),
552 after: StatSummary::new(),
553 }
554 }
555 pub fn record_before(&mut self, v: f64) {
557 self.before.record(v);
558 }
559 pub fn record_after(&mut self, v: f64) {
561 self.after.record(v);
562 }
563 pub fn mean_ratio(&self) -> Option<f64> {
565 let b = self.before.mean()?;
566 let a = self.after.mean()?;
567 if b.abs() < f64::EPSILON {
568 return None;
569 }
570 Some(a / b)
571 }
572}
573#[allow(dead_code)]
575pub struct PathBuf {
576 components: Vec<String>,
577}
578#[allow(dead_code)]
579impl PathBuf {
580 pub fn new() -> Self {
582 Self {
583 components: Vec::new(),
584 }
585 }
586 pub fn push(&mut self, comp: impl Into<String>) {
588 self.components.push(comp.into());
589 }
590 pub fn pop(&mut self) {
592 self.components.pop();
593 }
594 pub fn as_str(&self) -> String {
596 self.components.join("/")
597 }
598 pub fn depth(&self) -> usize {
600 self.components.len()
601 }
602 pub fn clear(&mut self) {
604 self.components.clear();
605 }
606}
607#[derive(Debug)]
609pub struct RegistrySnapshot {
610 instance_count: usize,
611}
612#[allow(dead_code)]
614pub struct RewriteRuleSet {
615 rules: Vec<RewriteRule>,
616}
617#[allow(dead_code)]
618impl RewriteRuleSet {
619 pub fn new() -> Self {
621 Self { rules: Vec::new() }
622 }
623 pub fn add(&mut self, rule: RewriteRule) {
625 self.rules.push(rule);
626 }
627 pub fn len(&self) -> usize {
629 self.rules.len()
630 }
631 pub fn is_empty(&self) -> bool {
633 self.rules.is_empty()
634 }
635 pub fn conditional_rules(&self) -> Vec<&RewriteRule> {
637 self.rules.iter().filter(|r| r.conditional).collect()
638 }
639 pub fn unconditional_rules(&self) -> Vec<&RewriteRule> {
641 self.rules.iter().filter(|r| !r.conditional).collect()
642 }
643 pub fn get(&self, name: &str) -> Option<&RewriteRule> {
645 self.rules.iter().find(|r| r.name == name)
646 }
647}
648#[allow(dead_code)]
650pub struct SparseVec<T: Default + Clone + PartialEq> {
651 entries: std::collections::HashMap<usize, T>,
652 default_: T,
653 logical_len: usize,
654}
655#[allow(dead_code)]
656impl<T: Default + Clone + PartialEq> SparseVec<T> {
657 pub fn new(len: usize) -> Self {
659 Self {
660 entries: std::collections::HashMap::new(),
661 default_: T::default(),
662 logical_len: len,
663 }
664 }
665 pub fn set(&mut self, idx: usize, val: T) {
667 if val == self.default_ {
668 self.entries.remove(&idx);
669 } else {
670 self.entries.insert(idx, val);
671 }
672 }
673 pub fn get(&self, idx: usize) -> &T {
675 self.entries.get(&idx).unwrap_or(&self.default_)
676 }
677 pub fn len(&self) -> usize {
679 self.logical_len
680 }
681 pub fn is_empty(&self) -> bool {
683 self.len() == 0
684 }
685 pub fn nnz(&self) -> usize {
687 self.entries.len()
688 }
689}
690#[allow(dead_code)]
692pub struct NonEmptyVec<T> {
693 head: T,
694 tail: Vec<T>,
695}
696#[allow(dead_code)]
697impl<T> NonEmptyVec<T> {
698 pub fn singleton(val: T) -> Self {
700 Self {
701 head: val,
702 tail: Vec::new(),
703 }
704 }
705 pub fn push(&mut self, val: T) {
707 self.tail.push(val);
708 }
709 pub fn first(&self) -> &T {
711 &self.head
712 }
713 pub fn last(&self) -> &T {
715 self.tail.last().unwrap_or(&self.head)
716 }
717 pub fn len(&self) -> usize {
719 1 + self.tail.len()
720 }
721 pub fn is_empty(&self) -> bool {
723 self.len() == 0
724 }
725 pub fn to_vec(&self) -> Vec<&T> {
727 let mut v = vec![&self.head];
728 v.extend(self.tail.iter());
729 v
730 }
731}
732#[allow(dead_code)]
734pub struct SlidingSum {
735 window: Vec<f64>,
736 capacity: usize,
737 pos: usize,
738 sum: f64,
739 count: usize,
740}
741#[allow(dead_code)]
742impl SlidingSum {
743 pub fn new(capacity: usize) -> Self {
745 Self {
746 window: vec![0.0; capacity],
747 capacity,
748 pos: 0,
749 sum: 0.0,
750 count: 0,
751 }
752 }
753 pub fn push(&mut self, val: f64) {
755 let oldest = self.window[self.pos];
756 self.sum -= oldest;
757 self.sum += val;
758 self.window[self.pos] = val;
759 self.pos = (self.pos + 1) % self.capacity;
760 if self.count < self.capacity {
761 self.count += 1;
762 }
763 }
764 pub fn sum(&self) -> f64 {
766 self.sum
767 }
768 pub fn mean(&self) -> Option<f64> {
770 if self.count == 0 {
771 None
772 } else {
773 Some(self.sum / self.count as f64)
774 }
775 }
776 pub fn count(&self) -> usize {
778 self.count
779 }
780}
781#[allow(dead_code)]
783pub struct WriteOnce<T> {
784 value: std::cell::Cell<Option<T>>,
785}
786#[allow(dead_code)]
787impl<T: Copy> WriteOnce<T> {
788 pub fn new() -> Self {
790 Self {
791 value: std::cell::Cell::new(None),
792 }
793 }
794 pub fn write(&self, val: T) -> bool {
796 if self.value.get().is_some() {
797 return false;
798 }
799 self.value.set(Some(val));
800 true
801 }
802 pub fn read(&self) -> Option<T> {
804 self.value.get()
805 }
806 pub fn is_written(&self) -> bool {
808 self.value.get().is_some()
809 }
810}
811#[allow(dead_code)]
813pub struct StackCalc {
814 stack: Vec<i64>,
815}
816#[allow(dead_code)]
817impl StackCalc {
818 pub fn new() -> Self {
820 Self { stack: Vec::new() }
821 }
822 pub fn push(&mut self, n: i64) {
824 self.stack.push(n);
825 }
826 pub fn add(&mut self) {
828 let b = self
829 .stack
830 .pop()
831 .expect("stack must have at least two values for add");
832 let a = self
833 .stack
834 .pop()
835 .expect("stack must have at least two values for add");
836 self.stack.push(a + b);
837 }
838 pub fn sub(&mut self) {
840 let b = self
841 .stack
842 .pop()
843 .expect("stack must have at least two values for sub");
844 let a = self
845 .stack
846 .pop()
847 .expect("stack must have at least two values for sub");
848 self.stack.push(a - b);
849 }
850 pub fn mul(&mut self) {
852 let b = self
853 .stack
854 .pop()
855 .expect("stack must have at least two values for mul");
856 let a = self
857 .stack
858 .pop()
859 .expect("stack must have at least two values for mul");
860 self.stack.push(a * b);
861 }
862 pub fn peek(&self) -> Option<i64> {
864 self.stack.last().copied()
865 }
866 pub fn depth(&self) -> usize {
868 self.stack.len()
869 }
870}
871#[allow(dead_code)]
873pub struct Stopwatch {
874 start: std::time::Instant,
875 splits: Vec<f64>,
876}
877#[allow(dead_code)]
878impl Stopwatch {
879 pub fn start() -> Self {
881 Self {
882 start: std::time::Instant::now(),
883 splits: Vec::new(),
884 }
885 }
886 pub fn split(&mut self) {
888 self.splits.push(self.elapsed_ms());
889 }
890 pub fn elapsed_ms(&self) -> f64 {
892 self.start.elapsed().as_secs_f64() * 1000.0
893 }
894 pub fn splits(&self) -> &[f64] {
896 &self.splits
897 }
898 pub fn num_splits(&self) -> usize {
900 self.splits.len()
901 }
902}
903#[allow(dead_code)]
905pub enum Either2<A, B> {
906 First(A),
908 Second(B),
910}
911#[allow(dead_code)]
912impl<A, B> Either2<A, B> {
913 pub fn is_first(&self) -> bool {
915 matches!(self, Either2::First(_))
916 }
917 pub fn is_second(&self) -> bool {
919 matches!(self, Either2::Second(_))
920 }
921 pub fn first(self) -> Option<A> {
923 match self {
924 Either2::First(a) => Some(a),
925 _ => None,
926 }
927 }
928 pub fn second(self) -> Option<B> {
930 match self {
931 Either2::Second(b) => Some(b),
932 _ => None,
933 }
934 }
935 pub fn map_first<C, F: FnOnce(A) -> C>(self, f: F) -> Either2<C, B> {
937 match self {
938 Either2::First(a) => Either2::First(f(a)),
939 Either2::Second(b) => Either2::Second(b),
940 }
941 }
942}
943#[allow(dead_code)]
945pub struct ConfigNode {
946 key: String,
947 value: Option<String>,
948 children: Vec<ConfigNode>,
949}
950#[allow(dead_code)]
951impl ConfigNode {
952 pub fn leaf(key: impl Into<String>, value: impl Into<String>) -> Self {
954 Self {
955 key: key.into(),
956 value: Some(value.into()),
957 children: Vec::new(),
958 }
959 }
960 pub fn section(key: impl Into<String>) -> Self {
962 Self {
963 key: key.into(),
964 value: None,
965 children: Vec::new(),
966 }
967 }
968 pub fn add_child(&mut self, child: ConfigNode) {
970 self.children.push(child);
971 }
972 pub fn key(&self) -> &str {
974 &self.key
975 }
976 pub fn value(&self) -> Option<&str> {
978 self.value.as_deref()
979 }
980 pub fn num_children(&self) -> usize {
982 self.children.len()
983 }
984 pub fn lookup(&self, path: &str) -> Option<&str> {
986 let mut parts = path.splitn(2, '.');
987 let head = parts.next()?;
988 let tail = parts.next();
989 if head != self.key {
990 return None;
991 }
992 match tail {
993 None => self.value.as_deref(),
994 Some(rest) => self.children.iter().find_map(|c| c.lookup_relative(rest)),
995 }
996 }
997 fn lookup_relative(&self, path: &str) -> Option<&str> {
998 let mut parts = path.splitn(2, '.');
999 let head = parts.next()?;
1000 let tail = parts.next();
1001 if head != self.key {
1002 return None;
1003 }
1004 match tail {
1005 None => self.value.as_deref(),
1006 Some(rest) => self.children.iter().find_map(|c| c.lookup_relative(rest)),
1007 }
1008 }
1009}
1010#[derive(Debug)]
1012pub struct NullResolver;
1013#[allow(dead_code)]
1015pub struct WindowIterator<'a, T> {
1016 pub(super) data: &'a [T],
1017 pub(super) pos: usize,
1018 pub(super) window: usize,
1019}
1020#[allow(dead_code)]
1021impl<'a, T> WindowIterator<'a, T> {
1022 pub fn new(data: &'a [T], window: usize) -> Self {
1024 Self {
1025 data,
1026 pos: 0,
1027 window,
1028 }
1029 }
1030}
1031#[allow(dead_code)]
1033pub struct StatSummary {
1034 count: u64,
1035 sum: f64,
1036 min: f64,
1037 max: f64,
1038}
1039#[allow(dead_code)]
1040impl StatSummary {
1041 pub fn new() -> Self {
1043 Self {
1044 count: 0,
1045 sum: 0.0,
1046 min: f64::INFINITY,
1047 max: f64::NEG_INFINITY,
1048 }
1049 }
1050 pub fn record(&mut self, val: f64) {
1052 self.count += 1;
1053 self.sum += val;
1054 if val < self.min {
1055 self.min = val;
1056 }
1057 if val > self.max {
1058 self.max = val;
1059 }
1060 }
1061 pub fn mean(&self) -> Option<f64> {
1063 if self.count == 0 {
1064 None
1065 } else {
1066 Some(self.sum / self.count as f64)
1067 }
1068 }
1069 pub fn min(&self) -> Option<f64> {
1071 if self.count == 0 {
1072 None
1073 } else {
1074 Some(self.min)
1075 }
1076 }
1077 pub fn max(&self) -> Option<f64> {
1079 if self.count == 0 {
1080 None
1081 } else {
1082 Some(self.max)
1083 }
1084 }
1085 pub fn count(&self) -> u64 {
1087 self.count
1088 }
1089}
1090#[allow(dead_code)]
1092pub struct FocusStack<T> {
1093 items: Vec<T>,
1094}
1095#[allow(dead_code)]
1096impl<T> FocusStack<T> {
1097 pub fn new() -> Self {
1099 Self { items: Vec::new() }
1100 }
1101 pub fn focus(&mut self, item: T) {
1103 self.items.push(item);
1104 }
1105 pub fn blur(&mut self) -> Option<T> {
1107 self.items.pop()
1108 }
1109 pub fn current(&self) -> Option<&T> {
1111 self.items.last()
1112 }
1113 pub fn depth(&self) -> usize {
1115 self.items.len()
1116 }
1117 pub fn is_empty(&self) -> bool {
1119 self.items.is_empty()
1120 }
1121}
1122#[allow(dead_code)]
1124pub struct TokenBucket {
1125 capacity: u64,
1126 tokens: u64,
1127 refill_per_ms: u64,
1128 last_refill: std::time::Instant,
1129}
1130#[allow(dead_code)]
1131impl TokenBucket {
1132 pub fn new(capacity: u64, refill_per_ms: u64) -> Self {
1134 Self {
1135 capacity,
1136 tokens: capacity,
1137 refill_per_ms,
1138 last_refill: std::time::Instant::now(),
1139 }
1140 }
1141 pub fn try_consume(&mut self, n: u64) -> bool {
1143 self.refill();
1144 if self.tokens >= n {
1145 self.tokens -= n;
1146 true
1147 } else {
1148 false
1149 }
1150 }
1151 fn refill(&mut self) {
1152 let now = std::time::Instant::now();
1153 let elapsed_ms = now.duration_since(self.last_refill).as_millis() as u64;
1154 if elapsed_ms > 0 {
1155 let new_tokens = elapsed_ms * self.refill_per_ms;
1156 self.tokens = (self.tokens + new_tokens).min(self.capacity);
1157 self.last_refill = now;
1158 }
1159 }
1160 pub fn available(&self) -> u64 {
1162 self.tokens
1163 }
1164 pub fn capacity(&self) -> u64 {
1166 self.capacity
1167 }
1168}
1169#[allow(dead_code)]
1171#[derive(Clone, Debug, Default)]
1172pub struct InstanceImpl {
1173 impls: Vec<MethodImpl>,
1175}
1176impl InstanceImpl {
1177 #[allow(dead_code)]
1179 pub fn new() -> Self {
1180 Self::default()
1181 }
1182 #[allow(dead_code)]
1184 pub fn add(&mut self, impl_: MethodImpl) {
1185 self.impls.push(impl_);
1186 }
1187 #[allow(dead_code)]
1189 pub fn get(&self, method: &Name) -> Option<&MethodImpl> {
1190 self.impls.iter().find(|m| &m.method_name == method)
1191 }
1192 #[allow(dead_code)]
1194 pub fn len(&self) -> usize {
1195 self.impls.len()
1196 }
1197 #[allow(dead_code)]
1199 pub fn is_empty(&self) -> bool {
1200 self.impls.is_empty()
1201 }
1202 #[allow(dead_code)]
1204 pub fn count_defaults(&self) -> usize {
1205 self.impls.iter().filter(|m| m.is_default).count()
1206 }
1207 #[allow(dead_code)]
1209 pub fn method_names(&self) -> Vec<&Name> {
1210 self.impls.iter().map(|m| &m.method_name).collect()
1211 }
1212}
1213#[allow(dead_code)]
1215pub struct TransitiveClosure {
1216 adj: Vec<Vec<usize>>,
1217 n: usize,
1218}
1219#[allow(dead_code)]
1220impl TransitiveClosure {
1221 pub fn new(n: usize) -> Self {
1223 Self {
1224 adj: vec![Vec::new(); n],
1225 n,
1226 }
1227 }
1228 pub fn add_edge(&mut self, from: usize, to: usize) {
1230 if from < self.n {
1231 self.adj[from].push(to);
1232 }
1233 }
1234 pub fn reachable_from(&self, start: usize) -> Vec<usize> {
1236 let mut visited = vec![false; self.n];
1237 let mut queue = std::collections::VecDeque::new();
1238 queue.push_back(start);
1239 while let Some(node) = queue.pop_front() {
1240 if node >= self.n || visited[node] {
1241 continue;
1242 }
1243 visited[node] = true;
1244 for &next in &self.adj[node] {
1245 queue.push_back(next);
1246 }
1247 }
1248 (0..self.n).filter(|&i| visited[i]).collect()
1249 }
1250 pub fn can_reach(&self, from: usize, to: usize) -> bool {
1252 self.reachable_from(from).contains(&to)
1253 }
1254}
1255#[allow(dead_code)]
1257pub struct SimpleDag {
1258 edges: Vec<Vec<usize>>,
1260}
1261#[allow(dead_code)]
1262impl SimpleDag {
1263 pub fn new(n: usize) -> Self {
1265 Self {
1266 edges: vec![Vec::new(); n],
1267 }
1268 }
1269 pub fn add_edge(&mut self, from: usize, to: usize) {
1271 if from < self.edges.len() {
1272 self.edges[from].push(to);
1273 }
1274 }
1275 pub fn successors(&self, node: usize) -> &[usize] {
1277 self.edges.get(node).map(|v| v.as_slice()).unwrap_or(&[])
1278 }
1279 pub fn can_reach(&self, from: usize, to: usize) -> bool {
1281 let mut visited = vec![false; self.edges.len()];
1282 self.dfs(from, to, &mut visited)
1283 }
1284 fn dfs(&self, cur: usize, target: usize, visited: &mut Vec<bool>) -> bool {
1285 if cur == target {
1286 return true;
1287 }
1288 if cur >= visited.len() || visited[cur] {
1289 return false;
1290 }
1291 visited[cur] = true;
1292 for &next in self.successors(cur) {
1293 if self.dfs(next, target, visited) {
1294 return true;
1295 }
1296 }
1297 false
1298 }
1299 pub fn topological_sort(&self) -> Option<Vec<usize>> {
1301 let n = self.edges.len();
1302 let mut in_degree = vec![0usize; n];
1303 for succs in &self.edges {
1304 for &s in succs {
1305 if s < n {
1306 in_degree[s] += 1;
1307 }
1308 }
1309 }
1310 let mut queue: std::collections::VecDeque<usize> =
1311 (0..n).filter(|&i| in_degree[i] == 0).collect();
1312 let mut order = Vec::new();
1313 while let Some(node) = queue.pop_front() {
1314 order.push(node);
1315 for &s in self.successors(node) {
1316 if s < n {
1317 in_degree[s] -= 1;
1318 if in_degree[s] == 0 {
1319 queue.push_back(s);
1320 }
1321 }
1322 }
1323 }
1324 if order.len() == n {
1325 Some(order)
1326 } else {
1327 None
1328 }
1329 }
1330 pub fn num_nodes(&self) -> usize {
1332 self.edges.len()
1333 }
1334}
1335#[derive(Clone, Debug)]
1340pub struct TypeClass {
1341 pub name: Name,
1343 pub params: Vec<Name>,
1345 pub ty: Expr,
1347 pub methods: Vec<Method>,
1349 pub super_classes: Vec<Name>,
1351 pub is_prop: bool,
1353}
1354impl TypeClass {
1355 pub fn new(name: Name, params: Vec<Name>, ty: Expr) -> Self {
1357 Self {
1358 name,
1359 params,
1360 ty,
1361 methods: Vec::new(),
1362 super_classes: Vec::new(),
1363 is_prop: false,
1364 }
1365 }
1366 pub fn add_method(&mut self, method: Method) {
1368 self.methods.push(method);
1369 }
1370 pub fn add_super(&mut self, super_name: Name) {
1372 self.super_classes.push(super_name);
1373 }
1374 pub fn mark_prop(mut self) -> Self {
1376 self.is_prop = true;
1377 self
1378 }
1379 pub fn find_method(&self, name: &Name) -> Option<&Method> {
1381 self.methods.iter().find(|m| &m.name == name)
1382 }
1383 pub fn has_super(&self, name: &Name) -> bool {
1385 self.super_classes.contains(name)
1386 }
1387 pub fn method_count(&self) -> usize {
1389 self.methods.len()
1390 }
1391 pub fn is_empty(&self) -> bool {
1393 self.methods.is_empty()
1394 }
1395 pub fn method_names(&self) -> impl Iterator<Item = &Name> {
1397 self.methods.iter().map(|m| &m.name)
1398 }
1399 pub fn has_super_classes(&self) -> bool {
1401 !self.super_classes.is_empty()
1402 }
1403 pub fn arity(&self) -> usize {
1405 self.params.len()
1406 }
1407}
1408#[derive(Clone, Debug)]
1412pub struct Instance {
1413 pub class: Name,
1415 pub ty: Expr,
1417 pub priority: i32,
1419 pub methods: HashMap<String, Expr>,
1421 pub instance_name: Option<Name>,
1423 pub is_local: bool,
1425}
1426impl Instance {
1427 pub fn new(class: Name, ty: Expr) -> Self {
1429 Self {
1430 class,
1431 ty,
1432 priority: 100,
1433 methods: HashMap::new(),
1434 instance_name: None,
1435 is_local: false,
1436 }
1437 }
1438 pub fn named(class: Name, ty: Expr, name: Name) -> Self {
1440 Self {
1441 class,
1442 ty,
1443 priority: 100,
1444 methods: HashMap::new(),
1445 instance_name: Some(name),
1446 is_local: false,
1447 }
1448 }
1449 pub fn with_priority(mut self, priority: i32) -> Self {
1451 self.priority = priority;
1452 self
1453 }
1454 pub fn as_local(mut self) -> Self {
1456 self.is_local = true;
1457 self
1458 }
1459 pub fn add_method_impl(&mut self, method_name: impl Into<String>, impl_expr: Expr) {
1461 self.methods.insert(method_name.into(), impl_expr);
1462 }
1463 pub fn get_method_impl(&self, method_name: &str) -> Option<&Expr> {
1465 self.methods.get(method_name)
1466 }
1467 pub fn implements_all(&self, class: &TypeClass) -> bool {
1469 class
1470 .methods
1471 .iter()
1472 .all(|m| self.methods.contains_key(&m.name.to_string()))
1473 }
1474 pub fn implemented_count(&self) -> usize {
1476 self.methods.len()
1477 }
1478 pub fn is_named(&self) -> bool {
1480 self.instance_name.is_some()
1481 }
1482}
1483#[derive(Clone, Debug)]
1485pub struct Method {
1486 pub name: Name,
1488 pub ty: Expr,
1490 pub has_default: bool,
1492 pub index: usize,
1494}
1495impl Method {
1496 pub fn new(name: Name, ty: Expr, index: usize) -> Self {
1498 Self {
1499 name,
1500 ty,
1501 has_default: false,
1502 index,
1503 }
1504 }
1505 pub fn with_default(name: Name, ty: Expr, index: usize) -> Self {
1507 Self {
1508 name,
1509 ty,
1510 has_default: true,
1511 index,
1512 }
1513 }
1514 pub fn set_default(mut self) -> Self {
1516 self.has_default = true;
1517 self
1518 }
1519}
1520#[derive(Clone, Debug, PartialEq, Eq)]
1522pub struct ClassEdge {
1523 pub parent: Name,
1525 pub child: Name,
1527}
1528impl ClassEdge {
1529 pub fn new(parent: Name, child: Name) -> Self {
1531 Self { parent, child }
1532 }
1533}
1534#[allow(dead_code)]
1536pub struct LabelSet {
1537 labels: Vec<String>,
1538}
1539#[allow(dead_code)]
1540impl LabelSet {
1541 pub fn new() -> Self {
1543 Self { labels: Vec::new() }
1544 }
1545 pub fn add(&mut self, label: impl Into<String>) {
1547 let s = label.into();
1548 if !self.labels.contains(&s) {
1549 self.labels.push(s);
1550 }
1551 }
1552 pub fn has(&self, label: &str) -> bool {
1554 self.labels.iter().any(|l| l == label)
1555 }
1556 pub fn count(&self) -> usize {
1558 self.labels.len()
1559 }
1560 pub fn all(&self) -> &[String] {
1562 &self.labels
1563 }
1564}
1565#[allow(dead_code)]
1567#[derive(Clone, Debug)]
1568pub struct MethodImpl {
1569 pub method_name: Name,
1571 pub impl_expr: Expr,
1573 pub is_default: bool,
1575}
1576impl MethodImpl {
1577 #[allow(dead_code)]
1579 pub fn custom(method: Name, expr: Expr) -> Self {
1580 Self {
1581 method_name: method,
1582 impl_expr: expr,
1583 is_default: false,
1584 }
1585 }
1586 #[allow(dead_code)]
1588 pub fn default_impl(method: Name, expr: Expr) -> Self {
1589 Self {
1590 method_name: method,
1591 impl_expr: expr,
1592 is_default: true,
1593 }
1594 }
1595}
1596#[derive(Clone, Debug)]
1598pub enum InstanceSearchResult {
1599 Found(Instance),
1601 Ambiguous(Vec<Instance>),
1603 NotFound,
1605}
1606impl InstanceSearchResult {
1607 pub fn is_found(&self) -> bool {
1609 matches!(self, InstanceSearchResult::Found(_))
1610 }
1611 pub fn is_ambiguous(&self) -> bool {
1613 matches!(self, InstanceSearchResult::Ambiguous(_))
1614 }
1615 pub fn into_instance(self) -> Option<Instance> {
1617 match self {
1618 InstanceSearchResult::Found(inst) => Some(inst),
1619 _ => None,
1620 }
1621 }
1622}