use super::TensorType;
use derive_new::new;
use proc_macro2::{Ident, TokenStream};
use quote::quote;
use std::collections::HashMap;
#[derive(Clone, Debug, Default)]
pub struct Scope {
variables: HashMap<Ident, Vec<TensorVariable>>,
}
#[derive(Clone, Debug, new)]
struct TensorVariable {
references: usize,
node_position: usize,
}
impl Scope {
pub fn tensor_register_variable(&mut self, tensor: &TensorType, node_position: usize) {
if let Some(variables) = self.variables.get_mut(&tensor.name) {
for variable in variables.iter_mut() {
if variable.node_position == node_position {
variable.references += 1;
return;
}
}
variables.push(TensorVariable::new(0, node_position));
} else {
self.variables.insert(
tensor.name.clone(),
vec![TensorVariable::new(0, node_position)],
);
}
}
pub fn tensor_register_future_use(&mut self, tensor: &TensorType, node_position: usize) {
if let Some(variables) = self.variables.get_mut(&tensor.name) {
for variable in variables.iter_mut().rev() {
if node_position >= variable.node_position {
variable.references += 1;
break;
}
}
} else {
panic!("No variable with name {}", tensor.name);
}
}
pub fn tensor_use_owned(&mut self, tensor: &TensorType, node_position: usize) -> TokenStream {
if let Some(variables) = self.variables.get_mut(&tensor.name) {
let mut count = 0;
let name = &tensor.name;
for variable in variables.iter_mut().rev() {
if node_position >= variable.node_position {
variable.references -= 1;
count = variable.references;
break;
}
}
if count > 0 {
quote! {
#name.clone()
}
} else {
quote! {
#name
}
}
} else {
panic!("No variable with name {}", &tensor.name);
}
}
}