use crate::{CompileError, ir};
use std::{
cell::{Ref, RefMut},
collections::BTreeMap,
};
use air_parser::ast::QualifiedIdentifier;
#[derive(Debug, Default, PartialEq, Eq)]
pub struct Graph {
functions: BTreeMap<QualifiedIdentifier, ir::Link<ir::Root>>,
evaluators: BTreeMap<QualifiedIdentifier, ir::Link<ir::Root>>,
pub boundary_constraints_roots: ir::Link<Vec<ir::Link<ir::Op>>>,
pub integrity_constraints_roots: ir::Link<Vec<ir::Link<ir::Op>>>,
pub buses: BTreeMap<QualifiedIdentifier, ir::Link<ir::Bus>>,
}
impl Graph {
pub fn create() -> ir::Link<Self> {
Graph::default().into()
}
pub fn insert_function(
&mut self,
ident: QualifiedIdentifier,
node: ir::Link<ir::Root>,
) -> Result<(), CompileError> {
if node.as_function().is_none() {
return Err(CompileError::Failed);
}
match self.functions.insert(ident, node) {
None => Ok(()),
Some(link) => {
if let ir::Root::None(_) = *link.borrow() {
Ok(())
} else {
Err(CompileError::Failed)
}
}
}
}
pub fn get_function_root(&self, ident: &QualifiedIdentifier) -> Option<ir::Link<ir::Root>> {
self.functions.get(ident).cloned()
}
pub fn get_function(&self, ident: &QualifiedIdentifier) -> Option<Ref<'_, ir::Function>> {
self.functions.get(ident).map(|n| n.as_function().unwrap())
}
pub fn get_function_mut(
&mut self,
ident: &QualifiedIdentifier,
) -> Option<RefMut<'_, ir::Function>> {
self.functions
.get_mut(ident)
.map(|n| n.as_function_mut().unwrap())
}
pub fn get_function_nodes(&self) -> Vec<ir::Link<ir::Root>> {
self.functions.values().cloned().collect()
}
pub fn insert_evaluator(
&mut self,
ident: QualifiedIdentifier,
node: ir::Link<ir::Root>,
) -> Result<(), CompileError> {
if node.as_evaluator().is_none() {
return Err(CompileError::Failed);
}
match self.evaluators.insert(ident, node) {
None => Ok(()),
Some(link) => {
if let ir::Root::None(_) = *link.borrow() {
Ok(())
} else {
Err(CompileError::Failed)
}
}
}
}
pub fn get_evaluator_root(&self, ident: &QualifiedIdentifier) -> Option<ir::Link<ir::Root>> {
self.evaluators.get(ident).cloned()
}
pub fn get_evaluator(&self, ident: &QualifiedIdentifier) -> Option<Ref<'_, ir::Evaluator>> {
self.evaluators
.get(ident)
.map(|n| n.as_evaluator().unwrap())
}
pub fn get_evaluator_mut(
&mut self,
ident: &QualifiedIdentifier,
) -> Option<RefMut<'_, ir::Evaluator>> {
self.evaluators
.get_mut(ident)
.map(|n| n.as_evaluator_mut().unwrap())
}
pub fn get_evaluator_nodes(&self) -> Vec<ir::Link<ir::Root>> {
self.evaluators.values().cloned().collect()
}
pub fn insert_boundary_constraints_root(&mut self, root: ir::Link<ir::Op>) {
if !self.boundary_constraints_roots.borrow().contains(&root) {
self.boundary_constraints_roots
.borrow_mut()
.push(root.clone());
}
}
pub fn remove_boundary_constraints_root(&mut self, root: ir::Link<ir::Op>) {
self.boundary_constraints_roots
.borrow_mut()
.retain(|n| *n != root);
}
pub fn insert_integrity_constraints_root(&mut self, root: ir::Link<ir::Op>) {
if !self.integrity_constraints_roots.borrow().contains(&root) {
self.integrity_constraints_roots
.borrow_mut()
.push(root.clone());
}
}
pub fn remove_integrity_constraints_root(&mut self, root: ir::Link<ir::Op>) {
self.boundary_constraints_roots
.borrow_mut()
.retain(|n| *n != root);
}
pub fn insert_bus(
&mut self,
ident: QualifiedIdentifier,
bus: ir::Link<ir::Bus>,
) -> Result<(), CompileError> {
self.buses
.insert(ident, bus)
.map_or(Ok(()), |_| Err(CompileError::Failed))
}
pub fn get_bus_link(&self, ident: &QualifiedIdentifier) -> Option<ir::Link<ir::Bus>> {
self.buses.get(ident).cloned()
}
pub fn get_bus(&self, ident: &QualifiedIdentifier) -> Option<Ref<'_, ir::Bus>> {
self.buses.get(ident).map(|n| n.borrow())
}
pub fn get_bus_mut(&mut self, ident: &QualifiedIdentifier) -> Option<RefMut<'_, ir::Bus>> {
self.buses.get_mut(ident).map(|n| n.borrow_mut())
}
pub fn get_bus_nodes(&self) -> Vec<ir::Link<ir::Bus>> {
self.buses.values().cloned().collect()
}
}