2022-05-31 16:28:12 +08:00

62 lines
1.6 KiB
Rust

use crate::ir::*;
use std::collections::{HashMap, HashSet};
pub type IrStructPool = HashMap<String, IrStruct>;
pub type IrEnumPool = HashMap<String, IrEnum>;
#[derive(Debug, Clone)]
pub struct IrFile {
pub funcs: Vec<IrFunc>,
pub struct_pool: IrStructPool,
pub enum_pool: IrEnumPool,
pub has_executor: bool,
}
impl IrFile {
/// [f] returns [true] if it wants to stop going to the *children* of this subtree
pub fn visit_types<F: FnMut(&IrType) -> bool>(
&self,
f: &mut F,
include_func_inputs: bool,
include_func_output: bool,
) {
for func in &self.funcs {
if include_func_inputs {
for field in &func.inputs {
field.ty.visit_types(f, self);
}
}
if include_func_output {
func.output.visit_types(f, self);
}
}
}
pub fn distinct_types(
&self,
include_func_inputs: bool,
include_func_output: bool,
) -> Vec<IrType> {
let mut seen_idents = HashSet::new();
let mut ans = Vec::new();
self.visit_types(
&mut |ty| {
let ident = ty.safe_ident();
let contains = seen_idents.contains(&ident);
if !contains {
seen_idents.insert(ident);
ans.push(ty.clone());
}
contains
},
include_func_inputs,
include_func_output,
);
// make the output change less when input change
ans.sort_by_key(|ty| ty.safe_ident());
ans
}
}